diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/FacetsParseElement.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/FacetsParseElement.java index 3dedeef25dc..6dad2e16cd1 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/FacetsParseElement.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/FacetsParseElement.java @@ -36,6 +36,7 @@ import org.elasticsearch.search.facet.query.QueryFacetCollectorParser; import org.elasticsearch.search.facet.range.RangeFacetCollectorParser; import org.elasticsearch.search.facet.statistical.StatisticalFacetCollectorParser; import org.elasticsearch.search.facet.terms.TermsFacetCollectorParser; +import org.elasticsearch.search.internal.ContextIndexSearcher; import org.elasticsearch.search.internal.SearchContext; import java.util.List; @@ -94,7 +95,7 @@ public class FacetsParseElement implements SearchParseElement { topLevelFieldName = parser.currentName(); } else if (token == XContentParser.Token.START_OBJECT) { FacetCollector facet = null; - boolean global = false; + String scope = ContextIndexSearcher.Scopes.MAIN; String facetFieldName = null; Filter filter = null; boolean cacheFilter = true; @@ -114,7 +115,11 @@ public class FacetsParseElement implements SearchParseElement { } } else if (token.isValue()) { if ("global".equals(facetFieldName)) { - global = parser.booleanValue(); + if (parser.booleanValue()) { + scope = ContextIndexSearcher.Scopes.GLOBAL; + } + } else if ("scope".equals(facetFieldName)) { + scope = parser.text(); } else if ("cache_filter".equals(facetFieldName) || "cacheFilter".equals(facetFieldName)) { cacheFilter = parser.booleanValue(); } @@ -131,11 +136,7 @@ public class FacetsParseElement implements SearchParseElement { facetCollectors = Lists.newArrayList(); } facetCollectors.add(facet); - if (global) { - context.searcher().addGlobalCollector(facet); - } else { - context.searcher().addCollector(facet); - } + context.searcher().addCollector(scope, facet); } } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/FacetsPhase.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/FacetsPhase.java index 0913af8dc49..d06cdd00445 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/FacetsPhase.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/facet/FacetsPhase.java @@ -30,6 +30,7 @@ import org.elasticsearch.search.SearchParseElement; import org.elasticsearch.search.SearchPhase; import org.elasticsearch.search.facet.collector.FacetCollector; import org.elasticsearch.search.facet.internal.InternalFacets; +import org.elasticsearch.search.internal.ContextIndexSearcher; import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.search.query.QueryPhaseExecutionException; @@ -59,22 +60,21 @@ public class FacetsPhase implements SearchPhase { } // run global facets ... - if (context.searcher().globalCollectors() != null) { + if (context.searcher().hasCollectors(ContextIndexSearcher.Scopes.GLOBAL)) { Query query = Queries.MATCH_ALL_QUERY; if (context.types().length > 0) { query = new FilteredQuery(query, context.filterCache().cache(context.mapperService().typesFilter(context.types()))); } - context.searcher().useGlobalCollectors(true); + context.searcher().processingScope(ContextIndexSearcher.Scopes.GLOBAL); try { context.searcher().search(query, NoopCollector.NOOP_COLLECTOR); } catch (IOException e) { throw new QueryPhaseExecutionException(context, "Failed to execute global facets", e); } finally { - context.searcher().useGlobalCollectors(false); + context.searcher().processedScope(); } } - SearchContextFacets contextFacets = context.facets(); List facets = Lists.newArrayListWithCapacity(2); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java index 7020b8d5922..9bcfe1167e1 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java @@ -21,6 +21,7 @@ package org.elasticsearch.search.internal; import org.apache.lucene.search.*; import org.elasticsearch.common.collect.Lists; +import org.elasticsearch.common.collect.Maps; import org.elasticsearch.common.lucene.MultiCollector; import org.elasticsearch.common.lucene.search.ExtendedIndexSearcher; import org.elasticsearch.index.engine.Engine; @@ -28,21 +29,26 @@ import org.elasticsearch.search.dfs.CachedDfSource; import java.io.IOException; import java.util.List; +import java.util.Map; /** * @author kimchy (shay.banon) */ public class ContextIndexSearcher extends ExtendedIndexSearcher { + public static final class Scopes { + public static final String MAIN = "_main_"; + public static final String GLOBAL = "_global_"; + public static final String NA = "_na_"; + } + private SearchContext searchContext; private CachedDfSource dfSource; - private List collectors; + private Map> scopeCollectors; - private List globalCollectors; - - private boolean useGlobalCollectors = false; + private String processingScope; public ContextIndexSearcher(SearchContext searchContext, Engine.Searcher searcher) { super(searcher.searcher()); @@ -53,30 +59,34 @@ public class ContextIndexSearcher extends ExtendedIndexSearcher { this.dfSource = dfSource; } - public void addCollector(Collector collector) { + public void addCollector(String scope, Collector collector) { + if (scopeCollectors == null) { + scopeCollectors = Maps.newHashMap(); + } + List collectors = scopeCollectors.get(scope); if (collectors == null) { collectors = Lists.newArrayList(); + scopeCollectors.put(scope, collectors); } collectors.add(collector); } - public List collectors() { - return collectors; - } - - public void addGlobalCollector(Collector collector) { - if (globalCollectors == null) { - globalCollectors = Lists.newArrayList(); + public boolean hasCollectors(String scope) { + if (scopeCollectors == null) { + return false; } - globalCollectors.add(collector); + if (!scopeCollectors.containsKey(scope)) { + return false; + } + return !scopeCollectors.get(scope).isEmpty(); } - public List globalCollectors() { - return globalCollectors; + public void processingScope(String scope) { + this.processingScope = scope; } - public void useGlobalCollectors(boolean useGlobalCollectors) { - this.useGlobalCollectors = useGlobalCollectors; + public void processedScope() { + this.processingScope = Scopes.NA; } @Override public Query rewrite(Query original) throws IOException { @@ -104,12 +114,9 @@ public class ContextIndexSearcher extends ExtendedIndexSearcher { if (searchContext.timeout() != null) { collector = new TimeLimitingCollector(collector, searchContext.timeout().millis()); } - if (useGlobalCollectors) { - if (globalCollectors != null) { - collector = new MultiCollector(collector, globalCollectors.toArray(new Collector[globalCollectors.size()])); - } - } else { - if (collectors != null) { + if (scopeCollectors != null) { + List collectors = scopeCollectors.get(processingScope); + if (collectors != null && !collectors.isEmpty()) { collector = new MultiCollector(collector, collectors.toArray(new Collector[collectors.size()])); } } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/query/QueryPhase.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/query/QueryPhase.java index be7a4b2b5f9..c95a76791c0 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/query/QueryPhase.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/query/QueryPhase.java @@ -32,6 +32,7 @@ import org.elasticsearch.search.SearchParseElement; import org.elasticsearch.search.SearchParseException; import org.elasticsearch.search.SearchPhase; import org.elasticsearch.search.facet.FacetsPhase; +import org.elasticsearch.search.internal.ContextIndexSearcher; import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.search.sort.SortParseElement; @@ -74,6 +75,7 @@ public class QueryPhase implements SearchPhase { } public void execute(SearchContext searchContext) throws QueryPhaseExecutionException { + searchContext.searcher().processingScope(ContextIndexSearcher.Scopes.MAIN); try { searchContext.queryResult().from(searchContext.from()); searchContext.queryResult().size(searchContext.size()); @@ -112,6 +114,8 @@ public class QueryPhase implements SearchPhase { searchContext.queryResult().topDocs(topDocs); } catch (Exception e) { throw new QueryPhaseExecutionException(searchContext, "Failed to execute main query", e); + } finally { + searchContext.searcher().processedScope(); } facetsPhase.execute(searchContext);