@Override public void search(Query query, Collector collector) throws IOException { // Wrap the caller's collector with various wrappers e.g. those used to siphon // matches off for aggregation or to impose a time-limit on collection. final boolean timeoutSet = searchContext.timeoutInMillis() != -1; final boolean terminateAfterSet = searchContext.terminateAfter() != SearchContext.DEFAULT_TERMINATE_AFTER; if (timeoutSet) { // TODO: change to use our own counter that uses the scheduler in ThreadPool // throws TimeLimitingCollector.TimeExceededException when timeout has reached collector = Lucene.wrapTimeLimitingCollector( collector, searchContext.timeEstimateCounter(), searchContext.timeoutInMillis()); } if (terminateAfterSet) { // throws Lucene.EarlyTerminationException when given count is reached collector = Lucene.wrapCountBasedEarlyTerminatingCollector(collector, searchContext.terminateAfter()); } if (currentState == Stage.MAIN_QUERY) { if (searchContext.parsedPostFilter() != null) { // 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 // since that is where the filter should only work final Weight filterWeight = createNormalizedWeight(searchContext.parsedPostFilter().query(), false); collector = new FilteredCollector(collector, filterWeight); } if (queryCollectors != null && !queryCollectors.isEmpty()) { ArrayList<Collector> allCollectors = new ArrayList<>(queryCollectors.values()); allCollectors.add(collector); collector = MultiCollector.wrap(allCollectors); } // apply the minimum score after multi collector so we filter aggs as well if (searchContext.minimumScore() != null) { collector = new MinimumScoreCollector(collector, searchContext.minimumScore()); } } super.search(query, collector); }
@Override public void search(List<LeafReaderContext> leaves, Weight weight, Collector collector) throws IOException { final boolean timeoutSet = searchContext.timeoutInMillis() != -1; final boolean terminateAfterSet = searchContext.terminateAfter() != SearchContext.DEFAULT_TERMINATE_AFTER; if (timeoutSet) { // TODO: change to use our own counter that uses the scheduler in ThreadPool // throws TimeLimitingCollector.TimeExceededException when timeout has reached collector = Lucene.wrapTimeLimitingCollector( collector, searchContext.timeEstimateCounter(), searchContext.timeoutInMillis()); } if (terminateAfterSet) { // throws Lucene.EarlyTerminationException when given count is reached collector = Lucene.wrapCountBasedEarlyTerminatingCollector(collector, searchContext.terminateAfter()); } if (currentState == Stage.MAIN_QUERY) { if (searchContext.parsedPostFilter() != null) { // 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 // since that is where the filter should only work collector = new FilteredCollector(collector, searchContext.parsedPostFilter().filter()); } if (queryCollectors != null && !queryCollectors.isEmpty()) { ArrayList<Collector> allCollectors = new ArrayList<>(queryCollectors.values()); allCollectors.add(collector); collector = MultiCollector.wrap(allCollectors); } // apply the minimum score after multi collector so we filter aggs as well if (searchContext.minimumScore() != null) { collector = new MinimumScoreCollector(collector, searchContext.minimumScore()); } } // we only compute the doc id set once since within a context, we execute the same query // always... try { if (timeoutSet || terminateAfterSet) { try { super.search(leaves, weight, collector); } catch (TimeLimitingCollector.TimeExceededException e) { assert timeoutSet : "TimeExceededException thrown even though timeout wasn't set"; searchContext.queryResult().searchTimedOut(true); } catch (Lucene.EarlyTerminationException e) { assert terminateAfterSet : "EarlyTerminationException thrown even though terminateAfter wasn't set"; searchContext.queryResult().terminatedEarly(true); } if (terminateAfterSet && searchContext.queryResult().terminatedEarly() == null) { searchContext.queryResult().terminatedEarly(false); } } else { super.search(leaves, weight, collector); } } finally { searchContext.clearReleasables(Lifetime.COLLECTION); } }