From 504ad01ab9d06310587d61f0a0e6e5916e52d75b Mon Sep 17 00:00:00 2001 From: Sergey Klyuykov Date: Tue, 26 Jul 2016 01:14:45 +0000 Subject: [PATCH 1/2] Change 'match' to 'filtered' for __contains case. --- django_elasticsearch/query.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/django_elasticsearch/query.py b/django_elasticsearch/query.py index c2804c7..3022752 100644 --- a/django_elasticsearch/query.py +++ b/django_elasticsearch/query.py @@ -158,9 +158,9 @@ def make_search_body(self): if operator == 'contains': nested_update(filters, - {'query': {'match': {field_name: {'query': value}}}}) - if len(filters['query']['match'].items()) > 1: - raise NotImplementedError("multi_match is not implemented.") + {'query': {'filtered': {"filter": {'terms': { field_name: value }}}}}) + if len(filters['query']['filtered']["filter"]['terms'].items()) > 1: + raise NotImplementedError("multi_terms is not implemented.") elif operator == 'isnull': if value: filtr = {'missing': {'field': field_name}} From 3ec647a210d0df910abd5ef43829ae467275a2a3 Mon Sep 17 00:00:00 2001 From: Sergey Klyuykov Date: Tue, 26 Jul 2016 23:39:36 +0000 Subject: [PATCH 2/2] Add operator __in to MyModel.es.filter() for search in list. --- django_elasticsearch/query.py | 9 +++++++-- readme.md | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/django_elasticsearch/query.py b/django_elasticsearch/query.py index 3022752..b3dba75 100644 --- a/django_elasticsearch/query.py +++ b/django_elasticsearch/query.py @@ -156,11 +156,16 @@ def make_search_body(self): if is_nested and isinstance(value, Model): value = value.id - if operator == 'contains': + if operator == 'in': nested_update(filters, {'query': {'filtered': {"filter": {'terms': { field_name: value }}}}}) if len(filters['query']['filtered']["filter"]['terms'].items()) > 1: raise NotImplementedError("multi_terms is not implemented.") + elif operator == 'contains': + nested_update(filters, + {'query': {'match': {field_name: {'query': value}}}}) + if len(filters['query']['match'].items()) > 1: + raise NotImplementedError("multi_match is not implemented.") elif operator == 'isnull': if value: filtr = {'missing': {'field': field_name}} @@ -321,7 +326,7 @@ def filter(self, **kwargs): return clone def sanitize_lookup(self, lookup): - valid_operators = ['exact', 'not', 'should', 'range', 'gt', 'lt', 'gte', 'lte', 'contains', 'isnull'] + valid_operators = ['exact', 'not', 'should', 'range', 'gt', 'lt', 'gte', 'lte', 'contains', 'in', 'isnull'] words = lookup.split('__') fields = [word for word in words if word not in valid_operators] # this is also django's default lookup type diff --git a/readme.md b/readme.md index ae9fd5d..12e0f6d 100644 --- a/readme.md +++ b/readme.md @@ -269,7 +269,7 @@ Note that es.search automatically add the default facets set on the model to the * **es.queryset.order_by**(**kwargs) * **es.queryset.filter**(**kwargs) - Accepted lookups are: __exact, __should, __contains, __gt, __gte, __lt, __lte, __range + Accepted lookups are: __exact, __should, __contains, __in, __gt, __gte, __lt, __lte, __range Just like in django, the default lookup is __exact. See the [bool query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html) for a difference between __exact (which maps to 'must') and __should.