A neater approach of for processing should clauses before must or must_not clauses.
This commit is contained in:
parent
52edc4c652
commit
f22510cab5
|
@ -31,7 +31,9 @@ import org.elasticsearch.common.lucene.docset.DocIdSets;
|
||||||
import org.elasticsearch.common.lucene.docset.NotDocIdSet;
|
import org.elasticsearch.common.lucene.docset.NotDocIdSet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to {@link org.apache.lucene.queries.BooleanFilter}.
|
* Similar to {@link org.apache.lucene.queries.BooleanFilter}.
|
||||||
|
@ -78,7 +80,6 @@ public class XBooleanFilter extends Filter implements Iterable<FilterClause> {
|
||||||
boolean hasNonEmptyShouldClause = false;
|
boolean hasNonEmptyShouldClause = false;
|
||||||
boolean hasMustClauses = false;
|
boolean hasMustClauses = false;
|
||||||
boolean hasMustNotClauses = false;
|
boolean hasMustNotClauses = false;
|
||||||
boolean mustOrMustNotBeforeShould = false;
|
|
||||||
for (int i = 0; i < clauses.size(); i++) {
|
for (int i = 0; i < clauses.size(); i++) {
|
||||||
FilterClause clause = clauses.get(i);
|
FilterClause clause = clauses.get(i);
|
||||||
DocIdSet set = clause.getFilter().getDocIdSet(context, acceptDocs);
|
DocIdSet set = clause.getFilter().getDocIdSet(context, acceptDocs);
|
||||||
|
@ -88,9 +89,6 @@ public class XBooleanFilter extends Filter implements Iterable<FilterClause> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else if (clause.getOccur() == Occur.SHOULD) {
|
} else if (clause.getOccur() == Occur.SHOULD) {
|
||||||
if (!hasShouldClauses && (hasMustClauses || hasMustNotClauses)) {
|
|
||||||
mustOrMustNotBeforeShould = true;
|
|
||||||
}
|
|
||||||
hasShouldClauses = true;
|
hasShouldClauses = true;
|
||||||
if (DocIdSets.isEmpty(set)) {
|
if (DocIdSets.isEmpty(set)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -115,35 +113,11 @@ public class XBooleanFilter extends Filter implements Iterable<FilterClause> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mustOrMustNotBeforeShould) {
|
// now, go over the clauses and apply the "fast" ones first...
|
||||||
// Sort the clause only once if we encounter a should before a must or must_not clause
|
|
||||||
Collections.sort(clauses, new Comparator<FilterClause>() {
|
|
||||||
@Override
|
|
||||||
public int compare(FilterClause o1, FilterClause o2) {
|
|
||||||
if (o1.getOccur() != o2.getOccur()) {
|
|
||||||
return o1.getOccur() == Occur.SHOULD ? -1 : 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Because we sorted the clause we also need to sort the result clauses
|
|
||||||
Collections.sort(results, new Comparator<ResultClause>() {
|
|
||||||
@Override
|
|
||||||
public int compare(ResultClause o1, ResultClause o2) {
|
|
||||||
if (o1.clause.getOccur() != o2.clause.getOccur()) {
|
|
||||||
return o1.clause.getOccur() == Occur.SHOULD ? -1 : 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// now, go over the clauses and apply the "fast" ones...
|
|
||||||
hasNonEmptyShouldClause = false;
|
hasNonEmptyShouldClause = false;
|
||||||
boolean hasBits = false;
|
boolean hasBits = false;
|
||||||
|
// But first we need to handle the "fast" should clauses, otherwise a should clause can unset docs
|
||||||
|
// that don't match with a must or must_not clause.
|
||||||
for (int i = 0; i < results.size(); i++) {
|
for (int i = 0; i < results.size(); i++) {
|
||||||
ResultClause clause = results.get(i);
|
ResultClause clause = results.get(i);
|
||||||
// we apply bits in based ones (slow) in the second run
|
// we apply bits in based ones (slow) in the second run
|
||||||
|
@ -161,7 +135,18 @@ public class XBooleanFilter extends Filter implements Iterable<FilterClause> {
|
||||||
res = new FixedBitSet(reader.maxDoc());
|
res = new FixedBitSet(reader.maxDoc());
|
||||||
}
|
}
|
||||||
res.or(it);
|
res.or(it);
|
||||||
} else if (clause.clause.getOccur() == Occur.MUST) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we safely handle the "fast" must and must_not clauses.
|
||||||
|
for (int i = 0; i < results.size(); i++) {
|
||||||
|
ResultClause clause = results.get(i);
|
||||||
|
// we apply bits in based ones (slow) in the second run
|
||||||
|
if (clause.bits != null) {
|
||||||
|
hasBits = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (clause.clause.getOccur() == Occur.MUST) {
|
||||||
DocIdSetIterator it = clause.docIdSet.iterator();
|
DocIdSetIterator it = clause.docIdSet.iterator();
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
Loading…
Reference in New Issue