mirror of
https://github.com/wagtail/wagtail.git
synced 2024-12-01 11:41:20 +01:00
Special case date lookups for searching
This commit is contained in:
parent
aefff4e56c
commit
45de8f0daa
@ -1,5 +1,7 @@
|
||||
from warnings import warn
|
||||
|
||||
from django.db.models.functions.datetime import Extract as ExtractDate
|
||||
from django.db.models.functions.datetime import ExtractYear
|
||||
from django.db.models.lookups import Lookup
|
||||
from django.db.models.query import QuerySet
|
||||
from django.db.models.sql.where import SubqueryConstraint, WhereNode
|
||||
@ -88,7 +90,16 @@ class BaseSearchQueryCompiler:
|
||||
def _get_filters_from_where_node(self, where_node, check_only=False):
|
||||
# Check if this is a leaf node
|
||||
if isinstance(where_node, Lookup):
|
||||
field_attname = where_node.lhs.target.attname
|
||||
if isinstance(where_node.lhs, ExtractDate):
|
||||
if isinstance(where_node.lhs, ExtractYear):
|
||||
field_attname = where_node.lhs.lhs.target.attname
|
||||
else:
|
||||
raise FilterError(
|
||||
'Cannot apply filter on search results: "' + where_node.lhs.lookup_name
|
||||
+ '" queries are not supported.'
|
||||
)
|
||||
else:
|
||||
field_attname = where_node.lhs.target.attname
|
||||
lookup = where_node.lookup_name
|
||||
value = where_node.rhs
|
||||
|
||||
|
@ -176,6 +176,19 @@ class ElasticsearchCommonSearchBackendTests(BackendTests):
|
||||
results = self.backend.search(MATCH_ALL, models.Book)[110:]
|
||||
self.assertEqual(len(results), 54)
|
||||
|
||||
def test_search_with_date_filter(self):
|
||||
after_1900 = models.Book.objects.filter(publication_date__year__gt=1900)
|
||||
|
||||
results = self.backend.search(MATCH_ALL, after_1900)
|
||||
self.assertEqual(len(after_1900), len(results))
|
||||
|
||||
# Filtering by date not supported, should throw a FilterError
|
||||
from wagtail.search.backends.base import FilterError
|
||||
|
||||
in_jan = models.Book.objects.filter(publication_date__month=1)
|
||||
with self.assertRaises(FilterError):
|
||||
self.backend.search(MATCH_ALL, in_jan)
|
||||
|
||||
# Elasticsearch always does prefix matching on `partial_match` fields,
|
||||
# even when we don’t use `Prefix`.
|
||||
@unittest.expectedFailure
|
||||
|
@ -333,6 +333,17 @@ class TestElasticsearch5SearchQuery(TestCase):
|
||||
expected_result = {'match_phrase': {'title': "Hello world"}}
|
||||
self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
|
||||
|
||||
def test_year_filter(self):
|
||||
# Create a query
|
||||
query_compiler = self.query_compiler_class(models.Book.objects.filter(publication_date__year__gt=1900), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'bool': {'filter': [
|
||||
{'match': {'content_type': 'searchtests.Book'}},
|
||||
{'range': {'publication_date_filter': {'gt': 1900}}}
|
||||
], 'must': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}}
|
||||
self.assertDictEqual(query_compiler.get_query(), expected_result)
|
||||
|
||||
|
||||
class TestElasticsearch5SearchResults(TestCase):
|
||||
fixtures = ['search']
|
||||
|
@ -333,6 +333,17 @@ class TestElasticsearch6SearchQuery(TestCase):
|
||||
expected_result = {'match_phrase': {'title': "Hello world"}}
|
||||
self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
|
||||
|
||||
def test_year_filter(self):
|
||||
# Create a query
|
||||
query_compiler = self.query_compiler_class(models.Book.objects.filter(publication_date__year=1900), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'bool': {'filter': [
|
||||
{'match': {'content_type': 'searchtests.Book'}},
|
||||
{'term': {'publication_date_filter': 1900}}
|
||||
], 'must': {'multi_match': {'query': 'Hello', 'fields': ['_all_text', '_edgengrams']}}}}
|
||||
self.assertDictEqual(query_compiler.get_query(), expected_result)
|
||||
|
||||
|
||||
class TestElasticsearch6SearchResults(TestCase):
|
||||
fixtures = ['search']
|
||||
|
@ -333,6 +333,17 @@ class TestElasticsearch7SearchQuery(TestCase):
|
||||
expected_result = {'match_phrase': {'title': "Hello world"}}
|
||||
self.assertDictEqual(query_compiler.get_inner_query(), expected_result)
|
||||
|
||||
def test_year_filter(self):
|
||||
# Create a query
|
||||
query_compiler = self.query_compiler_class(models.Book.objects.filter(publication_date__year__lt=1900), "Hello")
|
||||
|
||||
# Check it
|
||||
expected_result = {'bool': {'filter': [
|
||||
{'match': {'content_type': 'searchtests.Book'}},
|
||||
{'range': {'publication_date_filter': {'lt': 1900}}}
|
||||
], 'must': {'multi_match': {'query': 'Hello', 'fields': ['_all_text', '_edgengrams']}}}}
|
||||
self.assertDictEqual(query_compiler.get_query(), expected_result)
|
||||
|
||||
|
||||
class TestElasticsearch7SearchResults(TestCase):
|
||||
fixtures = ['search']
|
||||
|
Loading…
Reference in New Issue
Block a user