diff --git a/server/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java b/server/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java index 4c3c8944cf347..36c8856b122f0 100644 --- a/server/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java +++ b/server/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java @@ -424,12 +424,19 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) throws changed |= rewriteClauses(queryRewriteContext, mustNotClauses, newBuilder::mustNot); changed |= rewriteClauses(queryRewriteContext, filterClauses, newBuilder::filter); changed |= rewriteClauses(queryRewriteContext, shouldClauses, newBuilder::should); + // early termination when must clause is empty and optional clauses is returning MatchNoneQueryBuilder + if(mustClauses.size() == 0 && filterClauses.size() == 0 && shouldClauses.size() > 0 + && newBuilder.shouldClauses.stream().allMatch(b -> b instanceof MatchNoneQueryBuilder)) { + return new MatchNoneQueryBuilder(); + } + // lets do some early termination and prevent any kind of rewriting if we have a mandatory query that is a MatchNoneQueryBuilder Optional any = Stream.concat(newBuilder.mustClauses.stream(), newBuilder.filterClauses.stream()) .filter(b -> b instanceof MatchNoneQueryBuilder).findAny(); if (any.isPresent()) { return any.get(); } + if (changed) { newBuilder.adjustPureNegative = adjustPureNegative; newBuilder.minimumShouldMatch = minimumShouldMatch; diff --git a/server/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java index 10a31d8054801..1a1609fe7c50e 100644 --- a/server/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java @@ -371,5 +371,20 @@ public void testRewriteWithMatchNone() throws IOException { .filter(new MatchNoneQueryBuilder())); rewritten = Rewriteable.rewrite(boolQueryBuilder, createShardContext()); assertEquals(new MatchNoneQueryBuilder(), rewritten); + + boolQueryBuilder = new BoolQueryBuilder(); + boolQueryBuilder.should(new WrapperQueryBuilder(new MatchNoneQueryBuilder().toString())); + rewritten = Rewriteable.rewrite(boolQueryBuilder, createShardContext()); + assertEquals(new MatchNoneQueryBuilder(), rewritten); + + boolQueryBuilder = new BoolQueryBuilder(); + boolQueryBuilder.should(new TermQueryBuilder("foo", "bar")); + boolQueryBuilder.should(new WrapperQueryBuilder(new MatchNoneQueryBuilder().toString())); + rewritten = Rewriteable.rewrite(boolQueryBuilder, createShardContext()); + assertNotEquals(new MatchNoneQueryBuilder(), rewritten); + + boolQueryBuilder = new BoolQueryBuilder(); + rewritten = Rewriteable.rewrite(boolQueryBuilder, createShardContext()); + assertNotEquals(new MatchNoneQueryBuilder(), rewritten); } }