Skip to content

Commit

Permalink
LUCENE-9446: In boolean rewrite, remove MatchAllDocsQuery filter clau…
Browse files Browse the repository at this point in the history
…ses (#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`.
  • Loading branch information
jtibshirani authored and jpountz committed Aug 4, 2020
1 parent e21f9fc commit 8356966
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
3 changes: 3 additions & 0 deletions lucene/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ Improvements
* LUCENE-9440: FieldInfo#checkConsistency called twice from Lucene50(60)FieldInfosFormat#read;
Removed the (redundant?) assert and do these checks for real. (Yauheni Putsykovich)

* LUCENE-9446: In BooleanQuery rewrite, always remove MatchAllDocsQuery filter clauses
when possible. (Julie Tibshirani)

Optimizations
---------------------

Expand Down
12 changes: 7 additions & 5 deletions lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,13 @@ public Query rewrite(IndexReader reader) throws IOException {
}
}

// 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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,28 @@ public void testRemoveMatchAllFilter() throws IOException {
.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 {
Expand Down

0 comments on commit 8356966

Please sign in to comment.