From 745b977ce784aa49e65735767aff73f5760365f2 Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Thu, 3 Sep 2015 16:09:58 +0200 Subject: [PATCH] Optimize scrolls for constant-score queries. We currently optimize scroll when sort=_doc because docs are returned in order. But documents are also returned in order when sorting by score and the query gives constant scores. This optimization has the nice side-effect of also optimizing scrolls with the default `match_all` query. --- .../org/elasticsearch/search/query/QueryPhase.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/elasticsearch/search/query/QueryPhase.java b/core/src/main/java/org/elasticsearch/search/query/QueryPhase.java index a7c022aba28..054d33866c7 100644 --- a/core/src/main/java/org/elasticsearch/search/query/QueryPhase.java +++ b/core/src/main/java/org/elasticsearch/search/query/QueryPhase.java @@ -112,6 +112,18 @@ public class QueryPhase implements SearchPhase { aggregationPhase.execute(searchContext); } + private static boolean returnsDocsInOrder(Query query, Sort sort) { + if (sort == null || Sort.RELEVANCE.equals(sort)) { + // sort by score + // queries that return constant scores will return docs in index + // order since Lucene tie-breaks on the doc id + return query.getClass() == ConstantScoreQuery.class + || query.getClass() == MatchAllDocsQuery.class; + } else { + return Sort.INDEXORDER.equals(sort); + } + } + /** * In a package-private method so that it can be tested without having to * wire everything (mapperService, etc.) @@ -165,7 +177,7 @@ public class QueryPhase implements SearchPhase { numDocs = Math.min(searchContext.size(), totalNumDocs); lastEmittedDoc = scrollContext.lastEmittedDoc; - if (Sort.INDEXORDER.equals(searchContext.sort())) { + if (returnsDocsInOrder(query, searchContext.sort())) { if (scrollContext.totalHits == -1) { // first round assert scrollContext.lastEmittedDoc == null;