diff --git a/docs/searching.rst b/docs/searching.rst index a54ee37..602782c 100644 --- a/docs/searching.rst +++ b/docs/searching.rst @@ -307,7 +307,7 @@ field action Elasticsearch query type ====================== ================================ (no action specified) Term query term Term query -terms Terms query +terms Terms query [5]_ in Terms query text Text query (`DEPRECATED`) match Match query [1]_ @@ -336,6 +336,10 @@ query_string Querystring query [3]_ the range at once. The range is inclusive on both sides and accepts a tuple with the lower value first and upper value second. +.. [5] The ``terms`` field action support also the ``minimum_should_match`` + parameter. If you pass a two elements list and the first element + is a list, the second element is treated as minimum_should_match. + .. seealso:: diff --git a/elasticutils/__init__.py b/elasticutils/__init__.py index e049e30..9318b85 100644 --- a/elasticutils/__init__.py +++ b/elasticutils/__init__.py @@ -41,7 +41,6 @@ None: 'term', # Default to term 'in': 'in', 'term': 'term', - 'terms': 'terms', 'prefix': 'prefix', 'match': 'match', 'match_phrase': 'match_phrase', @@ -1343,7 +1342,26 @@ def _process_query(self, query): return { 'range': {field_name: _boosted_value( field_action, field_action, key, val, boost)} - } + } + + elif field_action == 'terms': + minimum_should_match = 1 + + if len(val) == 2 and isinstance(val[0], (tuple, list)): + minimum_should_match = val[1] + val = val[0] + + value = { + 'terms': _boosted_value( + field_name, field_action, key, val, boost + ) + } + + if minimum_should_match > 1: + value['terms']['minimum_should_match'] = minimum_should_match + + return value + elif field_action == 'range': lower, upper = val diff --git a/elasticutils/tests/test_query.py b/elasticutils/tests/test_query.py index 23e4347..0524464 100644 --- a/elasticutils/tests/test_query.py +++ b/elasticutils/tests/test_query.py @@ -190,6 +190,7 @@ class QueryTest(ESTestCase): 'id': 1, 'foo': 'bar', 'tag': 'awesome', + 'attributes': ['awesome', 'boring'], 'width': '2', 'height': 7 }, @@ -197,6 +198,7 @@ class QueryTest(ESTestCase): 'id': 2, 'foo': 'bart', 'tag': 'boring', + 'attributes': ['awesome', 'car'], 'width': '7', 'height': 11 }, @@ -204,6 +206,7 @@ class QueryTest(ESTestCase): 'id': 3, 'foo': 'car', 'tag': 'awesome', + 'attributes': ['awesome', 'duck'], 'width': '5', 'height': 5 }, @@ -211,6 +214,7 @@ class QueryTest(ESTestCase): 'id': 4, 'foo': 'duck', 'tag': 'boat', + 'attributes': ['train', 'boat'], 'width': '11', 'height': 7 }, @@ -218,6 +222,7 @@ class QueryTest(ESTestCase): 'id': 5, 'foo': 'train car', 'tag': 'awesome', + 'attributes': ['car', 'boring'], 'width': '7', 'height': 2 } @@ -245,6 +250,12 @@ def test_q_terms(self): eq_(len(self.get_s().query(Q(foo__terms=['car', 'duck']))), 3) + # minumum should match support + + eq_(len(self.get_s().query(attributes__terms=(['awesome', 'boring'], 2))), 1) + + eq_(len(self.get_s().query(Q(attributes__terms=(['awesome', 'boring'], 2)))), 1) + def test_q_in(self): eq_(len(self.get_s().query(foo__in=['car', 'bar'])), 3)