Merge pull request #15571 from jimferenczi/min_should_match

Min should match greater than the number of optional clauses should return no result
This commit is contained in:
Jim Ferenczi 2015-12-21 16:06:51 +01:00
commit 96e29be7c6
4 changed files with 73 additions and 5 deletions

View File

@ -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;
}
}

View File

@ -273,8 +273,7 @@ public class BoolQueryBuilder extends AbstractQueryBuilder<BoolQueryBuilder> {
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;

View File

@ -254,6 +254,24 @@ public class BoolQueryBuilderTests extends AbstractQueryTestCase<BoolQueryBuilde
assertThat(innerBooleanClause2.getQuery(), instanceOf(MatchAllDocsQuery.class));
}
public void testMinShouldMatchBiggerThanNumberOfShouldClauses() throws Exception {
BooleanQuery bq = (BooleanQuery) parseQuery(
boolQuery()
.should(termQuery("foo", "bar"))
.should(termQuery("foo2", "bar2"))
.minimumNumberShouldMatch("3")
.buildAsBytes()).toQuery(createShardContext());
assertEquals(3, bq.getMinimumNumberShouldMatch());
bq = (BooleanQuery) parseQuery(
boolQuery()
.should(termQuery("foo", "bar"))
.should(termQuery("foo2", "bar2"))
.minimumNumberShouldMatch(3)
.buildAsBytes()).toQuery(createShardContext());
assertEquals(3, bq.getMinimumNumberShouldMatch());
}
public void testFromJson() throws IOException {
String query =
"{" +

View File

@ -1016,6 +1016,59 @@ public class SearchQueryIT extends ESIntegTestCase {
searchResponse = client().prepareSearch().setQuery(multiMatchQuery).get();
assertHitCount(searchResponse, 1l);
assertFirstHit(searchResponse, hasId("1"));
// Min should match > # 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() {