Skip to content
Browse files

Search API: Query Facet - Add global flag to control if the facet is …

…bounded to the search query or not, closes #50.
  • Loading branch information...
1 parent 40b0dfd commit f4f26d2118b1bc6f0d895ba990ede22b02e731b4 @kimchy kimchy committed Mar 5, 2010
View
28 ...asticsearch/src/main/java/org/elasticsearch/search/builder/SearchSourceFacetsBuilder.java
@@ -58,7 +58,22 @@ public SearchSourceFacetsBuilder facet(String name, JsonQueryBuilder query) {
if (queryFacets == null) {
queryFacets = newArrayListWithCapacity(2);
}
- queryFacets.add(new FacetQuery(name, query));
+ queryFacets.add(new FacetQuery(name, query, null));
+ return this;
+ }
+
+ /**
+ * Adds a query facet (which results in a count facet returned) with an option to
+ * be global on the index or bounded by the search query.
+ *
+ * @param name The logical name of the facet, it will be returned under the name
+ * @param query The query facet
+ */
+ public SearchSourceFacetsBuilder facet(String name, JsonQueryBuilder query, boolean global) {
+ if (queryFacets == null) {
+ queryFacets = newArrayListWithCapacity(2);
+ }
+ queryFacets.add(new FacetQuery(name, query, global));
return this;
}
@@ -78,6 +93,9 @@ public SearchSourceFacetsBuilder facet(String name, JsonQueryBuilder query) {
builder.startObject(facetQuery.name());
builder.field("query");
facetQuery.queryBuilder().toJson(builder, params);
+ if (facetQuery.global() != null) {
+ builder.field("global", facetQuery.global());
+ }
builder.endObject();
}
}
@@ -88,10 +106,12 @@ public SearchSourceFacetsBuilder facet(String name, JsonQueryBuilder query) {
private static class FacetQuery {
private final String name;
private final JsonQueryBuilder queryBuilder;
+ private final Boolean global;
- private FacetQuery(String name, JsonQueryBuilder queryBuilder) {
+ private FacetQuery(String name, JsonQueryBuilder queryBuilder, Boolean global) {
this.name = name;
this.queryBuilder = queryBuilder;
+ this.global = global;
}
public String name() {
@@ -101,5 +121,9 @@ public String name() {
public JsonQueryBuilder queryBuilder() {
return queryBuilder;
}
+
+ public Boolean global() {
+ return this.global;
+ }
}
}
View
53 modules/elasticsearch/src/main/java/org/elasticsearch/search/facets/FacetsParseElement.java
@@ -36,7 +36,8 @@
* facets : {
* queryExecution : "collect|idset",
* facet1: {
- * query : { ... }
+ * query : { ... },
+ * global : false
* }
* }
* </pre>
@@ -49,12 +50,12 @@
JsonToken token;
SearchContextFacets.QueryExecutionType queryExecutionType = SearchContextFacets.QueryExecutionType.COLLECT;
List<SearchContextFacets.QueryFacet> queryFacets = null;
+ String topLevelFieldName = null;
while ((token = jp.nextToken()) != JsonToken.END_OBJECT) {
if (token == JsonToken.FIELD_NAME) {
- String topLevelFieldName = jp.getCurrentName();
-
+ topLevelFieldName = jp.getCurrentName();
+ } else if (token == JsonToken.VALUE_STRING) {
if ("queryExecution".equals(topLevelFieldName)) {
- jp.nextToken(); // move to value
String text = jp.getText();
if ("collect".equals(text)) {
queryExecutionType = SearchContextFacets.QueryExecutionType.COLLECT;
@@ -63,26 +64,36 @@
} else {
throw new SearchParseException(context, "Unsupported query type [" + text + "]");
}
- } else {
-
- jp.nextToken(); // move to START_OBJECT
-
- jp.nextToken(); // move to FIELD_NAME
- String facetType = jp.getCurrentName();
-
- if ("query".equals(facetType)) {
- JsonIndexQueryParser indexQueryParser = (JsonIndexQueryParser) context.queryParser();
- Query facetQuery = indexQueryParser.parse(jp);
-
- if (queryFacets == null) {
- queryFacets = Lists.newArrayListWithCapacity(2);
+ }
+ } else if (token == JsonToken.START_OBJECT) {
+ SearchContextFacets.Facet facet = null;
+ boolean global = false;
+ String facetFieldName = null;
+ while ((token = jp.nextToken()) != JsonToken.END_OBJECT) {
+ if (token == JsonToken.FIELD_NAME) {
+ facetFieldName = jp.getCurrentName();
+ } else if (token == JsonToken.START_OBJECT) {
+ if ("query".equals(facetFieldName)) {
+ JsonIndexQueryParser indexQueryParser = (JsonIndexQueryParser) context.queryParser();
+ Query facetQuery = indexQueryParser.parse(jp);
+ facet = new SearchContextFacets.QueryFacet(topLevelFieldName, facetQuery);
+ if (queryFacets == null) {
+ queryFacets = Lists.newArrayListWithCapacity(2);
+ }
+ queryFacets.add((SearchContextFacets.QueryFacet) facet);
}
- queryFacets.add(new SearchContextFacets.QueryFacet(topLevelFieldName, facetQuery));
- } else {
- throw new SearchParseException(context, "Unsupported facet type [" + facetType + "] for facet name [" + topLevelFieldName + "]");
+ } else if (token == JsonToken.VALUE_TRUE) {
+ if ("global".equals(facetFieldName)) {
+ global = true;
+ }
+ } else if (token == JsonToken.VALUE_NUMBER_INT) {
+ global = jp.getIntValue() != 0;
}
- jp.nextToken();
}
+ if (facet == null) {
+ throw new SearchParseException(context, "No facet type found for [" + topLevelFieldName + "]");
+ }
+ facet.global(global);
}
}
View
34 modules/elasticsearch/src/main/java/org/elasticsearch/search/facets/FacetsPhase.java
@@ -21,9 +21,7 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.Filter;
-import org.apache.lucene.search.QueryWrapperFilter;
+import org.apache.lucene.search.*;
import org.apache.lucene.util.OpenBitSet;
import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.ElasticSearchIllegalStateException;
@@ -38,7 +36,7 @@
import java.util.Map;
/**
- * @author kimchy (Shay Banon)
+ * @author kimchy (shay.banon)
*/
public class FacetsPhase implements SearchPhase {
@@ -63,17 +61,27 @@
List<Facet> facets = Lists.newArrayListWithCapacity(2);
if (contextFacets.queryFacets() != null) {
for (SearchContextFacets.QueryFacet queryFacet : contextFacets.queryFacets()) {
- Filter facetFilter = new QueryWrapperFilter(queryFacet.query());
- facetFilter = context.filterCache().cache(facetFilter);
- long count;
- if (contextFacets.queryType() == SearchContextFacets.QueryExecutionType.COLLECT) {
- count = executeQueryCollectorCount(context, queryFacet, facetFilter);
- } else if (contextFacets.queryType() == SearchContextFacets.QueryExecutionType.IDSET) {
- count = executeQueryIdSetCount(context, queryFacet, facetFilter);
+ if (queryFacet.global()) {
+ try {
+ Query globalQuery = new ConstantScoreQuery(context.filterCache().cache(new QueryWrapperFilter(queryFacet.query())));
+ long count = Lucene.count(context.searcher(), globalQuery, -1.0f);
+ facets.add(new CountFacet(queryFacet.name(), count));
+ } catch (Exception e) {
+ throw new FacetPhaseExecutionException(queryFacet.name(), "Failed to execute global facet [" + queryFacet.query() + "]", e);
+ }
} else {
- throw new ElasticSearchIllegalStateException("No matching for type [" + contextFacets.queryType() + "]");
+ Filter facetFilter = new QueryWrapperFilter(queryFacet.query());
+ facetFilter = context.filterCache().cache(facetFilter);
+ long count;
+ if (contextFacets.queryType() == SearchContextFacets.QueryExecutionType.COLLECT) {
+ count = executeQueryCollectorCount(context, queryFacet, facetFilter);
+ } else if (contextFacets.queryType() == SearchContextFacets.QueryExecutionType.IDSET) {
+ count = executeQueryIdSetCount(context, queryFacet, facetFilter);
+ } else {
+ throw new ElasticSearchIllegalStateException("No matching for type [" + contextFacets.queryType() + "]");
+ }
+ facets.add(new CountFacet(queryFacet.name(), count));
}
- facets.add(new CountFacet(queryFacet.name(), count));
}
}
View
19 ...es/elasticsearch/src/main/java/org/elasticsearch/search/internal/SearchContextFacets.java
@@ -24,7 +24,7 @@
import java.util.List;
/**
- * @author kimchy (Shay Banon)
+ * @author kimchy (shay.banon)
*/
public class SearchContextFacets {
@@ -50,7 +50,22 @@ public QueryExecutionType queryType() {
return queryFacets;
}
- public static class QueryFacet {
+ public static abstract class Facet {
+ private boolean global;
+
+ protected Facet() {
+ }
+
+ public boolean global() {
+ return global;
+ }
+
+ public void global(boolean global) {
+ this.global = global;
+ }
+ }
+
+ public static class QueryFacet extends Facet {
private final String name;
private final Query query;
View
2 ...c/test/java/org/elasticsearch/test/integration/search/TransportTwoServersSearchTests.java
@@ -222,7 +222,7 @@ protected Client getClient() {
SearchSourceBuilder sourceBuilder = searchSource()
.query(termQuery("multi", "test"))
.from(0).size(20).explain(true)
- .facets(facets().facet("all", termQuery("multi", "test")).facet("test1", termQuery("name", "test1")));
+ .facets(facets().facet("all", termQuery("multi", "test"), true).facet("test1", termQuery("name", "test1")));
SearchResponse searchResponse = client.search(searchRequest("test").source(sourceBuilder)).actionGet();
assertThat(searchResponse.hits().totalHits(), equalTo(100l));

0 comments on commit f4f26d2

Please sign in to comment.
Something went wrong with that request. Please try again.