From 4d32cc0b9f6ac41dca4674bbbadbf1e677e5d305 Mon Sep 17 00:00:00 2001 From: Jim Ferenczi Date: Mon, 21 Dec 2015 14:29:48 +0100 Subject: [PATCH] Queries.calculateMinShouldMatch returns the number of "min should match" clauses that the user wanted even if the number of optional clauses is smaller than the provided number. In such case the query now returns no result. Closes #15521 --- .../common/lucene/search/Queries.java | 4 +- .../index/query/BoolQueryBuilder.java | 3 +- .../index/query/BoolQueryBuilderTests.java | 18 +++++++ .../search/query/SearchQueryIT.java | 53 +++++++++++++++++++ 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/common/lucene/search/Queries.java b/core/src/main/java/org/elasticsearch/common/lucene/search/Queries.java index 5ecd22eab1b..73c3fc9400d 100644 --- a/core/src/main/java/org/elasticsearch/common/lucene/search/Queries.java +++ b/core/src/main/java/org/elasticsearch/common/lucene/search/Queries.java @@ -179,8 +179,6 @@ public class Queries { result = calc < 0 ? result + calc : calc; } - return (optionalClauseCount < result ? - optionalClauseCount : (result < 0 ? 0 : result)); - + return result < 0 ? 0 : result; } } diff --git a/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java index b8170a3195a..69ee2a81061 100644 --- a/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java +++ b/core/src/main/java/org/elasticsearch/index/query/BoolQueryBuilder.java @@ -273,8 +273,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder { return new MatchAllDocsQuery(); } final String minimumShouldMatch; - if (context.isFilter() && this.minimumShouldMatch == null) { - //will be applied for real only if there are should clauses + if (context.isFilter() && this.minimumShouldMatch == null && shouldClauses.size() > 0) { minimumShouldMatch = "1"; } else { minimumShouldMatch = this.minimumShouldMatch; diff --git a/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java b/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java index b1a4f7ccde1..1c407fbaa0e 100644 --- a/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/BoolQueryBuilderTests.java @@ -254,6 +254,24 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase # optional clauses returns no docs. + multiMatchQuery = multiMatchQuery("value1 value2 value3", "field1", "field2"); + multiMatchQuery.minimumShouldMatch("4"); + searchResponse = client().prepareSearch().setQuery(multiMatchQuery).get(); + assertHitCount(searchResponse, 0l); + } + + public void testBoolQueryMinShouldMatchBiggerThanNumberOfShouldClauses() throws IOException { + createIndex("test"); + client().prepareIndex("test", "type1", "1").setSource("field1", new String[]{"value1", "value2", "value3"}).get(); + client().prepareIndex("test", "type1", "2").setSource("field2", "value1").get(); + refresh(); + + BoolQueryBuilder boolQuery = boolQuery() + .must(termQuery("field1", "value1")) + .should(boolQuery() + .should(termQuery("field1", "value1")) + .should(termQuery("field1", "value2")) + .minimumNumberShouldMatch(3)); + SearchResponse searchResponse = client().prepareSearch().setQuery(boolQuery).get(); + assertHitCount(searchResponse, 1l); + assertFirstHit(searchResponse, hasId("1")); + + boolQuery = boolQuery() + .must(termQuery("field1", "value1")) + .should(boolQuery() + .should(termQuery("field1", "value1")) + .should(termQuery("field1", "value2")) + .minimumNumberShouldMatch(1)) + // Only one should clause is defined, returns no docs. + .minimumNumberShouldMatch(2); + searchResponse = client().prepareSearch().setQuery(boolQuery).get(); + assertHitCount(searchResponse, 0l); + + boolQuery = boolQuery() + .should(termQuery("field1", "value1")) + .should(boolQuery() + .should(termQuery("field1", "value1")) + .should(termQuery("field1", "value2")) + .minimumNumberShouldMatch(3)) + .minimumNumberShouldMatch(1); + searchResponse = client().prepareSearch().setQuery(boolQuery).get(); + assertHitCount(searchResponse, 1l); + assertFirstHit(searchResponse, hasId("1")); + + boolQuery = boolQuery() + .must(termQuery("field1", "value1")) + .must(boolQuery() + .should(termQuery("field1", "value1")) + .should(termQuery("field1", "value2")) + .minimumNumberShouldMatch(3)); + searchResponse = client().prepareSearch().setQuery(boolQuery).get(); + assertHitCount(searchResponse, 0l); } public void testFuzzyQueryString() {