Simplified the rewrite logic for the parent/child queries.

This commit is contained in:
Martijn van Groningen 2013-07-04 22:27:44 +02:00
parent 08c3359e6f
commit 5f9581d4f0
4 changed files with 16 additions and 86 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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<Object, ParentDoc[]> 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