mirror of https://github.com/apache/lucene.git
LUCENE-9446: In boolean rewrite, remove MatchAllDocsQuery filter clauses (#1709)
Previously, we only removed 'match all' FILTER clauses if there was at least one MUST clause. Now they're also removed if there is another distinct FILTER clause. This lets boolean queries like `#field:value #*:*` be written to `#field:value`.
This commit is contained in:
parent
bd21da6eca
commit
b91a161283
|
@ -114,6 +114,8 @@ Improvements
|
|||
with doc values and points. In this case, there is an assumption that the same data is
|
||||
stored in these points and doc values (Mayya Sharipova, Jim Ferenczi, Adrien Grand)
|
||||
|
||||
* LUCENE-9446: In BooleanQuery rewrite, always remove MatchAllDocsQuery filter clauses
|
||||
when possible. (Julie Tibshirani)
|
||||
|
||||
Bug fixes
|
||||
|
||||
|
|
|
@ -315,11 +315,13 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
|
|||
}
|
||||
}
|
||||
|
||||
// remove FILTER clauses that are also MUST clauses
|
||||
// or that match all documents
|
||||
if (clauseSets.get(Occur.MUST).size() > 0 && clauseSets.get(Occur.FILTER).size() > 0) {
|
||||
final Set<Query> filters = new HashSet<Query>(clauseSets.get(Occur.FILTER));
|
||||
boolean modified = filters.remove(new MatchAllDocsQuery());
|
||||
// remove FILTER clauses that are also MUST clauses or that match all documents
|
||||
if (clauseSets.get(Occur.FILTER).size() > 0) {
|
||||
final Set<Query> filters = new HashSet<>(clauseSets.get(Occur.FILTER));
|
||||
boolean modified = false;
|
||||
if (filters.size() > 1 || clauseSets.get(Occur.MUST).isEmpty() == false) {
|
||||
modified = filters.remove(new MatchAllDocsQuery());
|
||||
}
|
||||
modified |= filters.removeAll(clauseSets.get(Occur.MUST));
|
||||
if (modified) {
|
||||
BooleanQuery.Builder builder = new BooleanQuery.Builder();
|
||||
|
|
|
@ -312,12 +312,28 @@ public class TestBooleanRewrites extends LuceneTestCase {
|
|||
.add(new TermQuery(new Term("foo", "baz")), Occur.MUST)
|
||||
.add(new MatchAllDocsQuery(), Occur.FILTER)
|
||||
.build();
|
||||
BooleanQuery expected = new BooleanQuery.Builder()
|
||||
Query expected = new BooleanQuery.Builder()
|
||||
.setMinimumNumberShouldMatch(bq.getMinimumNumberShouldMatch())
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.MUST)
|
||||
.add(new TermQuery(new Term("foo", "baz")), Occur.MUST)
|
||||
.build();
|
||||
assertEquals(expected, searcher.rewrite(bq));
|
||||
|
||||
bq = new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term("foo", "bar")), Occur.FILTER)
|
||||
.add(new MatchAllDocsQuery(), Occur.FILTER)
|
||||
.build();
|
||||
expected = new BoostQuery(new ConstantScoreQuery(
|
||||
new TermQuery(new Term("foo", "bar"))), 0.0f);
|
||||
assertEquals(expected, searcher.rewrite(bq));
|
||||
|
||||
bq = new BooleanQuery.Builder()
|
||||
.add(new MatchAllDocsQuery(), Occur.FILTER)
|
||||
.add(new MatchAllDocsQuery(), Occur.FILTER)
|
||||
.build();
|
||||
expected = new BoostQuery(new ConstantScoreQuery(
|
||||
new MatchAllDocsQuery()), 0.0f);
|
||||
assertEquals(expected, searcher.rewrite(bq));
|
||||
}
|
||||
|
||||
public void testRandom() throws IOException {
|
||||
|
|
Loading…
Reference in New Issue