From 6d4077020096e32a89606ae80dc4fa8b1080e89e Mon Sep 17 00:00:00 2001 From: Igor Motov Date: Sun, 4 Nov 2012 22:31:56 -0500 Subject: [PATCH] lucene 4: fixed facets and filtering aliases I am not completely sure about this one, but it reduces the number of failing tests from 98 to 31 so I am going to check it in. Please, review and fix it, if there is a better solution. Because of change in Lucene 4.0, ContextIndexSearcher was bypassed and elasticsearch filters and collectors were ignored. In lucene 3.6 the stack of Searcher search calls looked like this: search(Query query, int n) search(Query query, Filter filter, int n) search(Weight weight, Filter filter, int nDocs) search(Weight weight, Filter filter, ScoreDoc after, int nDocs) search(Weight weight, Filter filter, Collector collector) <-- this is ContextIndexSearcher was injecting combined filter and collector search(Weight weight, Filter filter, Collector collector) In Lucene 4.0 the stack looks like this: search(Query query, int n) search(Query query, Filter filter, int n) <-- here lucene wraps Query and Filter into Weight search(Weight weight, ScoreDoc after, int nDocs) search(List leaves, Weight weight, ScoreDoc after, int nDocs) search(List leaves, Weight weight, Collector collector) ... In other words, when we have Filter, we don't have a Collector yet, but when we have Collector, Filter is already wrapped inside Weight. The only way to fix for the problem that I could think of is by introducing two injection points: one for Filters and another one for Collectors: search(Query query, int n) search(Query query, Filter filter, int n) <-- here combined Filters are injected search(Weight weight, ScoreDoc after, int nDocs) search(List leaves, Weight weight, ScoreDoc after, int nDocs) search(List leaves, Weight weight, Collector collector) <-- here Collectors are injected Similar problem existed for count(), so I had to override search(Query query, Collector results) as well. --- .../search/internal/ContextIndexSearcher.java | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java b/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java index b6e7564b7ea..d32fa2ce7c7 100644 --- a/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java +++ b/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java @@ -133,8 +133,37 @@ public class ContextIndexSearcher extends IndexSearcher { return super.createNormalizedWeight(query); } + private Filter combinedFilter(Filter filter) { + Filter combinedFilter; + if (filter == null) { + combinedFilter = searchContext.aliasFilter(); + } else { + if (searchContext.aliasFilter() != null) { + combinedFilter = new AndFilter(ImmutableList.of(filter, searchContext.aliasFilter())); + } else { + combinedFilter = filter; + } + } + return combinedFilter; + } + @Override - public void search(Query query, Filter filter, Collector collector) throws IOException { + public void search(Query query, Collector results) throws IOException { + Filter filter = combinedFilter(null); + if (filter != null) { + super.search(wrapFilter(query, filter), results); + } else { + super.search(query, results); + } + } + + @Override + public TopDocs search(Query query, Filter filter, int n) throws IOException { + return super.search(query, combinedFilter(filter), n); + } + + @Override + public void search(List leaves, Weight weight, Collector collector) throws IOException { if (searchContext.parsedFilter() != null && Scopes.MAIN.equals(processingScope)) { // this will only get applied to the actual search collector and not // to any scoped collectors, also, it will only be applied to the main collector @@ -156,26 +185,16 @@ public class ContextIndexSearcher extends IndexSearcher { collector = new MinimumScoreCollector(collector, searchContext.minimumScore()); } - Filter combinedFilter; - if (filter == null) { - combinedFilter = searchContext.aliasFilter(); - } else { - if (searchContext.aliasFilter() != null) { - combinedFilter = new AndFilter(ImmutableList.of(filter, searchContext.aliasFilter())); - } else { - combinedFilter = filter; - } - } // we only compute the doc id set once since within a context, we execute the same query always... if (searchContext.timeoutInMillis() != -1) { try { - super.search(query, combinedFilter, collector); + super.search(leaves, weight, collector); } catch (TimeLimitingCollector.TimeExceededException e) { searchContext.queryResult().searchTimedOut(true); } } else { - super.search(query, combinedFilter, collector); + super.search(leaves, weight, collector); } }