internal change to scope based collectors

This commit is contained in:
kimchy 2010-11-28 14:57:17 +02:00
parent 8285ffe221
commit a222de1dbf
4 changed files with 46 additions and 34 deletions

View File

@ -36,6 +36,7 @@ import org.elasticsearch.search.facet.query.QueryFacetCollectorParser;
import org.elasticsearch.search.facet.range.RangeFacetCollectorParser; import org.elasticsearch.search.facet.range.RangeFacetCollectorParser;
import org.elasticsearch.search.facet.statistical.StatisticalFacetCollectorParser; import org.elasticsearch.search.facet.statistical.StatisticalFacetCollectorParser;
import org.elasticsearch.search.facet.terms.TermsFacetCollectorParser; import org.elasticsearch.search.facet.terms.TermsFacetCollectorParser;
import org.elasticsearch.search.internal.ContextIndexSearcher;
import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.search.internal.SearchContext;
import java.util.List; import java.util.List;
@ -94,7 +95,7 @@ public class FacetsParseElement implements SearchParseElement {
topLevelFieldName = parser.currentName(); topLevelFieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) { } else if (token == XContentParser.Token.START_OBJECT) {
FacetCollector facet = null; FacetCollector facet = null;
boolean global = false; String scope = ContextIndexSearcher.Scopes.MAIN;
String facetFieldName = null; String facetFieldName = null;
Filter filter = null; Filter filter = null;
boolean cacheFilter = true; boolean cacheFilter = true;
@ -114,7 +115,11 @@ public class FacetsParseElement implements SearchParseElement {
} }
} else if (token.isValue()) { } else if (token.isValue()) {
if ("global".equals(facetFieldName)) { 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)) { } else if ("cache_filter".equals(facetFieldName) || "cacheFilter".equals(facetFieldName)) {
cacheFilter = parser.booleanValue(); cacheFilter = parser.booleanValue();
} }
@ -131,11 +136,7 @@ public class FacetsParseElement implements SearchParseElement {
facetCollectors = Lists.newArrayList(); facetCollectors = Lists.newArrayList();
} }
facetCollectors.add(facet); facetCollectors.add(facet);
if (global) { context.searcher().addCollector(scope, facet);
context.searcher().addGlobalCollector(facet);
} else {
context.searcher().addCollector(facet);
}
} }
} }

View File

@ -30,6 +30,7 @@ import org.elasticsearch.search.SearchParseElement;
import org.elasticsearch.search.SearchPhase; import org.elasticsearch.search.SearchPhase;
import org.elasticsearch.search.facet.collector.FacetCollector; import org.elasticsearch.search.facet.collector.FacetCollector;
import org.elasticsearch.search.facet.internal.InternalFacets; import org.elasticsearch.search.facet.internal.InternalFacets;
import org.elasticsearch.search.internal.ContextIndexSearcher;
import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.search.query.QueryPhaseExecutionException; import org.elasticsearch.search.query.QueryPhaseExecutionException;
@ -59,22 +60,21 @@ public class FacetsPhase implements SearchPhase {
} }
// run global facets ... // run global facets ...
if (context.searcher().globalCollectors() != null) { if (context.searcher().hasCollectors(ContextIndexSearcher.Scopes.GLOBAL)) {
Query query = Queries.MATCH_ALL_QUERY; Query query = Queries.MATCH_ALL_QUERY;
if (context.types().length > 0) { if (context.types().length > 0) {
query = new FilteredQuery(query, context.filterCache().cache(context.mapperService().typesFilter(context.types()))); query = new FilteredQuery(query, context.filterCache().cache(context.mapperService().typesFilter(context.types())));
} }
context.searcher().useGlobalCollectors(true); context.searcher().processingScope(ContextIndexSearcher.Scopes.GLOBAL);
try { try {
context.searcher().search(query, NoopCollector.NOOP_COLLECTOR); context.searcher().search(query, NoopCollector.NOOP_COLLECTOR);
} catch (IOException e) { } catch (IOException e) {
throw new QueryPhaseExecutionException(context, "Failed to execute global facets", e); throw new QueryPhaseExecutionException(context, "Failed to execute global facets", e);
} finally { } finally {
context.searcher().useGlobalCollectors(false); context.searcher().processedScope();
} }
} }
SearchContextFacets contextFacets = context.facets(); SearchContextFacets contextFacets = context.facets();
List<Facet> facets = Lists.newArrayListWithCapacity(2); List<Facet> facets = Lists.newArrayListWithCapacity(2);

View File

@ -21,6 +21,7 @@ package org.elasticsearch.search.internal;
import org.apache.lucene.search.*; import org.apache.lucene.search.*;
import org.elasticsearch.common.collect.Lists; import org.elasticsearch.common.collect.Lists;
import org.elasticsearch.common.collect.Maps;
import org.elasticsearch.common.lucene.MultiCollector; import org.elasticsearch.common.lucene.MultiCollector;
import org.elasticsearch.common.lucene.search.ExtendedIndexSearcher; import org.elasticsearch.common.lucene.search.ExtendedIndexSearcher;
import org.elasticsearch.index.engine.Engine; import org.elasticsearch.index.engine.Engine;
@ -28,21 +29,26 @@ import org.elasticsearch.search.dfs.CachedDfSource;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @author kimchy (shay.banon) * @author kimchy (shay.banon)
*/ */
public class ContextIndexSearcher extends ExtendedIndexSearcher { 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 SearchContext searchContext;
private CachedDfSource dfSource; private CachedDfSource dfSource;
private List<Collector> collectors; private Map<String, List<Collector>> scopeCollectors;
private List<Collector> globalCollectors; private String processingScope;
private boolean useGlobalCollectors = false;
public ContextIndexSearcher(SearchContext searchContext, Engine.Searcher searcher) { public ContextIndexSearcher(SearchContext searchContext, Engine.Searcher searcher) {
super(searcher.searcher()); super(searcher.searcher());
@ -53,30 +59,34 @@ public class ContextIndexSearcher extends ExtendedIndexSearcher {
this.dfSource = dfSource; this.dfSource = dfSource;
} }
public void addCollector(Collector collector) { public void addCollector(String scope, Collector collector) {
if (scopeCollectors == null) {
scopeCollectors = Maps.newHashMap();
}
List<Collector> collectors = scopeCollectors.get(scope);
if (collectors == null) { if (collectors == null) {
collectors = Lists.newArrayList(); collectors = Lists.newArrayList();
scopeCollectors.put(scope, collectors);
} }
collectors.add(collector); collectors.add(collector);
} }
public List<Collector> collectors() { public boolean hasCollectors(String scope) {
return collectors; if (scopeCollectors == null) {
} return false;
public void addGlobalCollector(Collector collector) {
if (globalCollectors == null) {
globalCollectors = Lists.newArrayList();
} }
globalCollectors.add(collector); if (!scopeCollectors.containsKey(scope)) {
return false;
}
return !scopeCollectors.get(scope).isEmpty();
} }
public List<Collector> globalCollectors() { public void processingScope(String scope) {
return globalCollectors; this.processingScope = scope;
} }
public void useGlobalCollectors(boolean useGlobalCollectors) { public void processedScope() {
this.useGlobalCollectors = useGlobalCollectors; this.processingScope = Scopes.NA;
} }
@Override public Query rewrite(Query original) throws IOException { @Override public Query rewrite(Query original) throws IOException {
@ -104,12 +114,9 @@ public class ContextIndexSearcher extends ExtendedIndexSearcher {
if (searchContext.timeout() != null) { if (searchContext.timeout() != null) {
collector = new TimeLimitingCollector(collector, searchContext.timeout().millis()); collector = new TimeLimitingCollector(collector, searchContext.timeout().millis());
} }
if (useGlobalCollectors) { if (scopeCollectors != null) {
if (globalCollectors != null) { List<Collector> collectors = scopeCollectors.get(processingScope);
collector = new MultiCollector(collector, globalCollectors.toArray(new Collector[globalCollectors.size()])); if (collectors != null && !collectors.isEmpty()) {
}
} else {
if (collectors != null) {
collector = new MultiCollector(collector, collectors.toArray(new Collector[collectors.size()])); collector = new MultiCollector(collector, collectors.toArray(new Collector[collectors.size()]));
} }
} }

View File

@ -32,6 +32,7 @@ import org.elasticsearch.search.SearchParseElement;
import org.elasticsearch.search.SearchParseException; import org.elasticsearch.search.SearchParseException;
import org.elasticsearch.search.SearchPhase; import org.elasticsearch.search.SearchPhase;
import org.elasticsearch.search.facet.FacetsPhase; import org.elasticsearch.search.facet.FacetsPhase;
import org.elasticsearch.search.internal.ContextIndexSearcher;
import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.search.internal.SearchContext;
import org.elasticsearch.search.sort.SortParseElement; import org.elasticsearch.search.sort.SortParseElement;
@ -74,6 +75,7 @@ public class QueryPhase implements SearchPhase {
} }
public void execute(SearchContext searchContext) throws QueryPhaseExecutionException { public void execute(SearchContext searchContext) throws QueryPhaseExecutionException {
searchContext.searcher().processingScope(ContextIndexSearcher.Scopes.MAIN);
try { try {
searchContext.queryResult().from(searchContext.from()); searchContext.queryResult().from(searchContext.from());
searchContext.queryResult().size(searchContext.size()); searchContext.queryResult().size(searchContext.size());
@ -112,6 +114,8 @@ public class QueryPhase implements SearchPhase {
searchContext.queryResult().topDocs(topDocs); searchContext.queryResult().topDocs(topDocs);
} catch (Exception e) { } catch (Exception e) {
throw new QueryPhaseExecutionException(searchContext, "Failed to execute main query", e); throw new QueryPhaseExecutionException(searchContext, "Failed to execute main query", e);
} finally {
searchContext.searcher().processedScope();
} }
facetsPhase.execute(searchContext); facetsPhase.execute(searchContext);