Fixed #161 -- Supported range search filter

`range` was added in django-haystack commit 3994bfa199.
This commit is contained in:
Claude Paroz 2016-10-14 18:04:20 +02:00
parent 313ef57a55
commit de76bad3f0
2 changed files with 26 additions and 0 deletions

View file

@ -307,6 +307,15 @@ class SearchQueryTestCase(HaystackBackendTestCase, TestCase):
self.sq.add_filter(SQ(name__lte='m'))
self.assertExpectedQuery(self.sq.build_query(), 'VALUE_RANGE 3 a m')
def test_range(self):
self.sq.add_filter(SQ(django_id__range=[2, 4]))
self.assertExpectedQuery(self.sq.build_query(), 'VALUE_RANGE 1 000000000002 000000000004')
self.sq.add_filter(~SQ(django_id__range=[0, 2]))
self.assertExpectedQuery(self.sq.build_query(),
'(VALUE_RANGE 1 000000000002 000000000004 AND '
'(<alldocuments> AND_NOT VALUE_RANGE 1 000000000000 000000000002))')
self.assertEqual([result.pk for result in self.sq.get_results()], [3])
def test_multiple_filter_types(self):
self.sq.add_filter(SQ(content='why'))
self.sq.add_filter(SQ(pub_date__lte=datetime.datetime(2009, 2, 10, 1, 59, 0)))

View file

@ -1373,6 +1373,8 @@ class XapianSearchQuery(BaseSearchQuery):
query_list.append(self._filter_lt(term, field_name, field_type, is_not))
elif filter_type == 'lte':
query_list.append(self._filter_lte(term, field_name, field_type, is_not))
elif filter_type == 'range':
query_list.append(self._filter_range(term, field_name, field_type, is_not))
return query_list
def _all_query(self):
@ -1559,6 +1561,21 @@ class XapianSearchQuery(BaseSearchQuery):
)
return xapian.Query(xapian.Query.OP_VALUE_RANGE, pos, begin, end)
def _filter_range(self, term, field_name, field_type, is_not):
"""
Private method that returns a xapian.Query that searches for any term
that is between the values from the `term` list.
"""
vrp = XHValueRangeProcessor(self.backend)
pos, begin, end = vrp('%s:%s' % (field_name, _term_to_xapian_value(term[0], field_type)),
'%s' % _term_to_xapian_value(term[1], field_type))
if is_not:
return xapian.Query(xapian.Query.OP_AND_NOT,
self._all_query(),
xapian.Query(xapian.Query.OP_VALUE_RANGE, pos, begin, end)
)
return xapian.Query(xapian.Query.OP_VALUE_RANGE, pos, begin, end)
def _term_to_xapian_value(term, field_type):
"""