From c926ee32b33d53877705585e35de80a3a37be88d Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 12 Oct 2015 12:28:03 +0100 Subject: [PATCH] Implemented search ordering in Elasticsearch --- .../wagtailsearch/backends/elasticsearch.py | 43 ++++++++++++++++++- .../tests/test_elasticsearch_backend.py | 1 + 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/wagtail/wagtailsearch/backends/elasticsearch.py b/wagtail/wagtailsearch/backends/elasticsearch.py index 4dffc0f3db..b48b5f5f88 100644 --- a/wagtail/wagtailsearch/backends/elasticsearch.py +++ b/wagtail/wagtailsearch/backends/elasticsearch.py @@ -318,6 +318,37 @@ class ElasticSearchQuery(BaseSearchQuery): else: return inner_query + def get_sort(self): + # Ordering by relevance is the default in Elasticsearch + if self.order_by_relevance: + return + + # Get queryset and make sure its ordered + if self.queryset.ordered: + order_by_fields = self.queryset.query.order_by + sort = [] + + for order_by_field in order_by_fields: + reverse = False + field_name = order_by_field + + if order_by_field.startswith('-'): + reverse = True + field_name = order_by_field[1:] + + field = self._get_filterable_field(field_name) + field_index_name = field.get_index_name(self.queryset.model) + + sort.append({ + field_index_name: 'desc' if reverse else 'asc' + }) + + return sort + + else: + # Order by pk field + return ['pk'] + def __repr__(self): return json.dumps(self.get_query()) @@ -341,14 +372,22 @@ class ElasticSearchResults(BaseSearchResults): ), RemovedInWagtail14Warning, stacklevel=2) - return { + body = { 'query': self.query.to_es(), } else: - return { + body = { 'query': self.query.get_query() } + if not for_count: + sort = self.query.get_sort() + + if sort is not None: + body['sort'] = sort + + return body + def _do_search(self): # Params for elasticsearch query params = dict( diff --git a/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py b/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py index 0fed3266ed..b5b25b279d 100644 --- a/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py +++ b/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py @@ -383,6 +383,7 @@ class TestElasticSearchResults(TestCase): query = mock.MagicMock() query.queryset = models.SearchTest.objects.all() query.get_query.return_value = 'QUERY' + query.get_sort.return_value = None return self.ElasticSearchResults(backend, query) def construct_search_response(self, results):