diff --git a/elasticsearch_dsl/query.py b/elasticsearch_dsl/query.py index 04346539..e45955ca 100644 --- a/elasticsearch_dsl/query.py +++ b/elasticsearch_dsl/query.py @@ -208,8 +208,13 @@ def __and__(self, other): del q._params["minimum_should_match"] for qx in (self, other): - # TODO: percentages will fail here min_should_match = qx._min_should_match + # TODO: percentages or negative numbers will fail here + # for now we report an error + if not isinstance(min_should_match, int) or min_should_match < 0: + raise ValueError( + "Can only combine queries with positive integer values for minimum_should_match" + ) # all subqueries are required if len(qx.should) <= min_should_match: q.must.extend(qx.should) diff --git a/tests/test_query.py b/tests/test_query.py index dde4963c..4571e227 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -278,6 +278,28 @@ def test_bool_and_bool_with_min_should_match(): assert query.Q("bool", must=[qt1, qt2]) == q1 & q2 +def test_negative_min_should_match(): + qt1, qt2 = query.Match(f=1), query.Match(f=2) + q1 = query.Q("bool", minimum_should_match=-2, should=[qt1]) + q2 = query.Q("bool", minimum_should_match=1, should=[qt2]) + + with raises(ValueError): + q1 & q2 + with raises(ValueError): + q2 & q1 + + +def test_percentage_min_should_match(): + qt1, qt2 = query.Match(f=1), query.Match(f=2) + q1 = query.Q("bool", minimum_should_match="50%", should=[qt1]) + q2 = query.Q("bool", minimum_should_match=1, should=[qt2]) + + with raises(ValueError): + q1 & q2 + with raises(ValueError): + q2 & q1 + + def test_inverted_query_becomes_bool_with_must_not(): q = query.Match(f=42)