mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-04-24 23:27:25 -04:00
Rewrite match_all inside must_not (#85999)
A must_not with a match_all clause inside a bool query is currently not rewritten to a match_none query. This means that running a boolean query with "must_not":[{"terms":{"_tier":["data_frozen","data_cold"]}] is currently not rewritten as match_none on a cold/frozen tier node.
This commit is contained in:
parent
718a241449
commit
4c47daa8d6
4 changed files with 18 additions and 9 deletions
5
docs/changelog/85999.yaml
Normal file
5
docs/changelog/85999.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
pr: 85999
|
||||||
|
summary: Rewrite `match_all` inside `must_not`
|
||||||
|
area: Search
|
||||||
|
type: bug
|
||||||
|
issues: []
|
|
@ -21,6 +21,7 @@ import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||||
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
|
import org.elasticsearch.index.query.ConstantScoreQueryBuilder;
|
||||||
import org.elasticsearch.index.query.DisMaxQueryBuilder;
|
import org.elasticsearch.index.query.DisMaxQueryBuilder;
|
||||||
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
import org.elasticsearch.index.query.MatchAllQueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.MatchNoneQueryBuilder;
|
||||||
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
|
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
|
||||||
import org.elasticsearch.index.query.MatchQueryBuilder;
|
import org.elasticsearch.index.query.MatchQueryBuilder;
|
||||||
import org.elasticsearch.index.query.Operator;
|
import org.elasticsearch.index.query.Operator;
|
||||||
|
@ -84,10 +85,10 @@ public class QueryBuilderBWCIT extends AbstractFullClusterRestartTestCase {
|
||||||
""", new RangeQueryBuilder("long_field").from(1).to(9));
|
""", new RangeQueryBuilder("long_field").from(1).to(9));
|
||||||
addCandidate(
|
addCandidate(
|
||||||
"""
|
"""
|
||||||
"bool": { "must_not": [{"match_all": {}}], "must": [{"match_all": {}}], "filter": [{"match_all": {}}], \
|
"bool": { "must_not": [{"match_none": {}}], "must": [{"match_all": {}}], "filter": [{"match_all": {}}], \
|
||||||
"should": [{"match_all": {}}]}
|
"should": [{"match_all": {}}]}
|
||||||
""",
|
""",
|
||||||
new BoolQueryBuilder().mustNot(new MatchAllQueryBuilder())
|
new BoolQueryBuilder().mustNot(new MatchNoneQueryBuilder())
|
||||||
.must(new MatchAllQueryBuilder())
|
.must(new MatchAllQueryBuilder())
|
||||||
.filter(new MatchAllQueryBuilder())
|
.filter(new MatchAllQueryBuilder())
|
||||||
.should(new MatchAllQueryBuilder())
|
.should(new MatchAllQueryBuilder())
|
||||||
|
|
|
@ -29,9 +29,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.elasticsearch.common.lucene.search.Queries.fixNegativeQueryIfNeeded;
|
import static org.elasticsearch.common.lucene.search.Queries.fixNegativeQueryIfNeeded;
|
||||||
import static org.elasticsearch.search.SearchModule.INDICES_MAX_NESTED_DEPTH_SETTING;
|
import static org.elasticsearch.search.SearchModule.INDICES_MAX_NESTED_DEPTH_SETTING;
|
||||||
|
@ -385,11 +383,10 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// lets do some early termination and prevent any kind of rewriting if we have a mandatory query that is a MatchNoneQueryBuilder
|
// lets do some early termination and prevent any kind of rewriting if we have a mandatory query that is a MatchNoneQueryBuilder
|
||||||
Optional<QueryBuilder> any = Stream.concat(newBuilder.mustClauses.stream(), newBuilder.filterClauses.stream())
|
if (newBuilder.mustClauses.stream().anyMatch(b -> b instanceof MatchNoneQueryBuilder)
|
||||||
.filter(b -> b instanceof MatchNoneQueryBuilder)
|
|| newBuilder.filterClauses.stream().anyMatch(b -> b instanceof MatchNoneQueryBuilder)
|
||||||
.findAny();
|
|| newBuilder.mustNotClauses.stream().anyMatch(b -> b instanceof MatchAllQueryBuilder)) {
|
||||||
if (any.isPresent()) {
|
return new MatchNoneQueryBuilder();
|
||||||
return any.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
|
|
@ -425,6 +425,12 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
|
||||||
boolQueryBuilder = new BoolQueryBuilder();
|
boolQueryBuilder = new BoolQueryBuilder();
|
||||||
rewritten = Rewriteable.rewrite(boolQueryBuilder, createSearchExecutionContext());
|
rewritten = Rewriteable.rewrite(boolQueryBuilder, createSearchExecutionContext());
|
||||||
assertNotEquals(new MatchNoneQueryBuilder(), rewritten);
|
assertNotEquals(new MatchNoneQueryBuilder(), rewritten);
|
||||||
|
|
||||||
|
boolQueryBuilder = new BoolQueryBuilder();
|
||||||
|
boolQueryBuilder.filter(new TermQueryBuilder(TEXT_FIELD_NAME, "bar"));
|
||||||
|
boolQueryBuilder.mustNot(new WrapperQueryBuilder(new WrapperQueryBuilder(new MatchAllQueryBuilder().toString()).toString()));
|
||||||
|
rewritten = boolQueryBuilder.rewrite(createSearchExecutionContext());
|
||||||
|
assertEquals(new MatchNoneQueryBuilder(), rewritten);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue