diff --git a/src/main/java/org/elasticsearch/index/query/TopChildrenQueryParser.java b/src/main/java/org/elasticsearch/index/query/TopChildrenQueryParser.java index ff2c98c0bb6..26757b25d17 100644 --- a/src/main/java/org/elasticsearch/index/query/TopChildrenQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/TopChildrenQueryParser.java @@ -127,7 +127,7 @@ public class TopChildrenQueryParser implements QueryParser { if (searchContext == null) { throw new ElasticSearchIllegalStateException("[top_children] Can't execute, search context not set."); } - TopChildrenQuery childQuery = new TopChildrenQuery(searchContext, query, childType, parentType, scoreType, factor, incrementalFactor); + TopChildrenQuery childQuery = new TopChildrenQuery(query, childType, parentType, scoreType, factor, incrementalFactor); searchContext.addRewrite(childQuery); return childQuery; } diff --git a/src/main/java/org/elasticsearch/index/search/child/ChildrenQuery.java b/src/main/java/org/elasticsearch/index/search/child/ChildrenQuery.java index 0f7082f152e..220f76b5892 100644 --- a/src/main/java/org/elasticsearch/index/search/child/ChildrenQuery.java +++ b/src/main/java/org/elasticsearch/index/search/child/ChildrenQuery.java @@ -71,19 +71,6 @@ public class ChildrenQuery extends Query implements SearchContext.Rewrite { this.scoreType = scoreType; } - private ChildrenQuery(ChildrenQuery unProcessedQuery, Query rewrittenChildQuery) { - this.searchContext = unProcessedQuery.searchContext; - this.parentType = unProcessedQuery.parentType; - this.childType = unProcessedQuery.childType; - this.parentFilter = unProcessedQuery.parentFilter; - this.scoreType = unProcessedQuery.scoreType; - this.originalChildQuery = unProcessedQuery.originalChildQuery; - this.rewrittenChildQuery = rewrittenChildQuery; - - this.uidToScore = unProcessedQuery.uidToScore; - this.uidToCount = unProcessedQuery.uidToCount; - } - @Override public boolean equals(Object obj) { if (this == obj) { @@ -119,22 +106,12 @@ public class ChildrenQuery extends Query implements SearchContext.Rewrite { } @Override + // See TopChildrenQuery#rewrite public Query rewrite(IndexReader reader) throws IOException { - Query rewritten; if (rewrittenChildQuery == null) { - rewritten = originalChildQuery.rewrite(reader); - } else { - rewritten = rewrittenChildQuery; + rewrittenChildQuery = originalChildQuery.rewrite(reader); } - if (rewritten == rewrittenChildQuery) { - return this; - } - - // See TopChildrenQuery#rewrite - int index = searchContext.rewrites().indexOf(this); - ChildrenQuery rewrite = new ChildrenQuery(this, rewritten); - searchContext.rewrites().set(index, rewrite); - return rewrite; + return this; } @Override diff --git a/src/main/java/org/elasticsearch/index/search/child/ParentQuery.java b/src/main/java/org/elasticsearch/index/search/child/ParentQuery.java index d22255f4a71..550947d4eaa 100644 --- a/src/main/java/org/elasticsearch/index/search/child/ParentQuery.java +++ b/src/main/java/org/elasticsearch/index/search/child/ParentQuery.java @@ -61,16 +61,6 @@ public class ParentQuery extends Query implements SearchContext.Rewrite { this.childrenFilter = new ApplyAcceptedDocsFilter(childrenFilter); } - private ParentQuery(ParentQuery unwritten, Query rewrittenParentQuery) { - this.searchContext = unwritten.searchContext; - this.originalParentQuery = unwritten.originalParentQuery; - this.parentType = unwritten.parentType; - this.childrenFilter = unwritten.childrenFilter; - - this.rewrittenParentQuery = rewrittenParentQuery; - this.uidToScore = unwritten.uidToScore; - } - @Override public void contextRewrite(SearchContext searchContext) throws Exception { searchContext.idCache().refresh(searchContext.searcher().getTopReaderContext().leaves()); @@ -129,22 +119,12 @@ public class ParentQuery extends Query implements SearchContext.Rewrite { } @Override + // See TopChildrenQuery#rewrite public Query rewrite(IndexReader reader) throws IOException { - Query rewritten; if (rewrittenParentQuery == null) { - rewritten = originalParentQuery.rewrite(reader); - } else { - rewritten = rewrittenParentQuery; + rewrittenParentQuery = originalParentQuery.rewrite(reader); } - if (rewritten == rewrittenParentQuery) { - return this; - } - - // See TopChildrenQuery#rewrite - ParentQuery rewrite = new ParentQuery(this, rewritten); - int index = searchContext.rewrites().indexOf(this); - searchContext.rewrites().set(index, rewrite); - return rewrite; + return this; } @Override diff --git a/src/main/java/org/elasticsearch/index/search/child/TopChildrenQuery.java b/src/main/java/org/elasticsearch/index/search/child/TopChildrenQuery.java index 24c8425a12c..89d879d7ff9 100644 --- a/src/main/java/org/elasticsearch/index/search/child/TopChildrenQuery.java +++ b/src/main/java/org/elasticsearch/index/search/child/TopChildrenQuery.java @@ -53,7 +53,6 @@ import java.util.Set; */ public class TopChildrenQuery extends Query implements SearchContext.Rewrite { - private final SearchContext searchContext; private final String parentType; private final String childType; private final ScoreType scoreType; @@ -61,12 +60,12 @@ public class TopChildrenQuery extends Query implements SearchContext.Rewrite { private final int incrementalFactor; private final Query originalChildQuery; + // This field will hold the rewritten form of originalChildQuery, so that we can reuse it private Query rewrittenChildQuery; private ExtTHashMap parentDocs; // Note, the query is expected to already be filtered to only child type docs - public TopChildrenQuery(SearchContext searchContext, Query childQuery, String childType, String parentType, ScoreType scoreType, int factor, int incrementalFactor) { - this.searchContext = searchContext; + public TopChildrenQuery(Query childQuery, String childType, String parentType, ScoreType scoreType, int factor, int incrementalFactor) { this.originalChildQuery = childQuery; this.childType = childType; this.parentType = parentType; @@ -75,46 +74,20 @@ public class TopChildrenQuery extends Query implements SearchContext.Rewrite { this.incrementalFactor = incrementalFactor; } - private TopChildrenQuery(TopChildrenQuery existing, Query rewrittenChildQuery) { - this.searchContext = existing.searchContext; - this.originalChildQuery = existing.originalChildQuery; - this.parentType = existing.parentType; - this.childType = existing.childType; - this.scoreType = existing.scoreType; - this.factor = existing.factor; - this.incrementalFactor = existing.incrementalFactor; - this.parentDocs = existing.parentDocs; - this.rewrittenChildQuery = rewrittenChildQuery; - } - - - // Rewrite logic: + // Rewrite invocation logic: // 1) query_then_fetch (default): First contextRewrite and then rewrite is executed // 2) dfs_query_then_fetch:: First rewrite and then contextRewrite is executed. During query phase rewrite isn't // executed any more because searchContext#queryRewritten() returns true. - @Override public Query rewrite(IndexReader reader) throws IOException { - Query rewritten; if (rewrittenChildQuery == null) { - rewritten = originalChildQuery.rewrite(reader); - } else { - rewritten = rewrittenChildQuery; + rewrittenChildQuery = originalChildQuery.rewrite(reader); } - if (rewritten == rewrittenChildQuery) { - return this; - } - // We need to update the rewritten query also in the SearchContext#rewrites b/c we can run into this situation: - // 1) During parsing we set SearchContext#rewrites with queries that implement Rewrite. - // 2) Then during the dfs phase, the main query (which included this query and its child query) gets rewritten - // and updated in SearchContext. So different TopChildrenQuery instances are in SearchContext#rewrites and in the main query. - // 3) Then during the query phase first the queries that impl. Rewrite are executed, which will update their own data - // parentDocs Map. Then when the main query is executed, 0 results are found, b/c the main query holds a different - // TopChildrenQuery instance then in SearchContext#rewrites - int index = searchContext.rewrites().indexOf(this); - TopChildrenQuery rewrite = new TopChildrenQuery(this, rewritten); - searchContext.rewrites().set(index, rewrite); - return rewrite; + // We can always return the current instance, and we can do this b/c the child query is executed separately + // before the main query (other scope) in a different IS#search() invocation than the main query. + // In fact we only need override the rewrite method because for the dfs phase, to get also global document + // frequency for the child query. + return this; } @Override