Refactored some of the comon bits of query generation for phrase, all, and term based queries. Fixed 'in' based queries
This commit is contained in:
parent
f027e26644
commit
09c12d88f7
|
@ -120,16 +120,21 @@ class XapianSearchQueryTestCase(TestCase):
|
|||
# self.sq.add_filter(SQ(id__in=[1, 2, 3]))
|
||||
# self.assertEqual(self.sq.build_query().get_description(), 'Xapian::Query(why AND pub_date:[* TO "2009-02-10 01:59:00"] AND author:{daniel TO *} AND created:{* TO "2009-02-12 12:13:00"} AND title:[B TO *] AND (id:"1" OR id:"2" OR id:"3"))')
|
||||
|
||||
def test_build_query_in_filter_single_words(self):
|
||||
self.sq.add_filter(SQ(content='why'))
|
||||
self.sq.add_filter(SQ(title__in=["Dune", "Jaws"]))
|
||||
self.assertEqual(self.sq.build_query().get_description(), 'Xapian::Query((why AND (XTITLEdune OR XTITLEjaws)))')
|
||||
|
||||
def test_build_query_in_filter_multiple_words(self):
|
||||
self.sq.add_filter(SQ(content='why'))
|
||||
self.sq.add_filter(SQ(title__in=["A Famous Paper", "An Infamous Article"]))
|
||||
self.assertEqual(self.sq.build_query().get_description(), 'Xapian::Query((why AND (XTITLEa famous paper OR XTITLEan infamous article)))')
|
||||
self.assertEqual(self.sq.build_query().get_description(), 'Xapian::Query((why AND ((XTITLEa PHRASE 3 XTITLEfamous PHRASE 3 XTITLEpaper) OR (XTITLEan PHRASE 3 XTITLEinfamous PHRASE 3 XTITLEarticle))))')
|
||||
|
||||
# def test_build_query_not_in_filter_multiple_words(self):
|
||||
# self.sq.add_filter(SQ(content='why'))
|
||||
# self.sq.add_filter(~SQ(title__in=["A Famous Paper", "An Infamous Article"]))
|
||||
# self.assertEqual(self.sq.build_query().get_description(), 'Xapian::Query((why AND_NOT (XTITLEa famous paper OR XTITLEan infamous article)))')
|
||||
|
||||
#
|
||||
# def test_build_query_in_filter_datetime(self):
|
||||
# self.sq.add_filter(SQ(content='why'))
|
||||
# self.sq.add_filter(SQ(pub_date__in=[datetime.datetime(2009, 7, 6, 1, 56, 21)]))
|
||||
|
|
|
@ -952,19 +952,7 @@ class SearchQuery(BaseSearchQuery):
|
|||
elif filter_type == 'startswith':
|
||||
pass
|
||||
elif filter_type == 'in':
|
||||
query_list.append(
|
||||
xapian.Query(
|
||||
xapian.Query.OP_OR, [
|
||||
xapian.Query(
|
||||
'%s%s%s' % (
|
||||
DOCUMENT_CUSTOM_TERM_PREFIX,
|
||||
field.upper(),
|
||||
_marshal_value(possible_value)
|
||||
)
|
||||
) for possible_value in value
|
||||
]
|
||||
)
|
||||
)
|
||||
query_list.append(self._filter_in(value, field, is_not))
|
||||
|
||||
|
||||
if search_node.connector == 'OR':
|
||||
|
@ -976,50 +964,75 @@ class SearchQuery(BaseSearchQuery):
|
|||
if ' ' in value:
|
||||
if is_not:
|
||||
return xapian.Query(
|
||||
xapian.Query.OP_AND_NOT,
|
||||
xapian.Query(''),
|
||||
xapian.Query
|
||||
(xapian.Query.OP_PHRASE, value.split()
|
||||
)
|
||||
)
|
||||
xapian.Query.OP_AND_NOT, self._all_query(), self._phrase_query(value.split())
|
||||
)
|
||||
else:
|
||||
return xapian.Query(xapian.Query.OP_PHRASE, value.split())
|
||||
return self._phrase_query(value.split())
|
||||
else:
|
||||
if is_not:
|
||||
return xapian.Query(xapian.Query.OP_AND_NOT, '', value)
|
||||
return xapian.Query(xapian.Query.OP_AND_NOT, self._all_query(), self._term_query(value))
|
||||
else:
|
||||
return xapian.Query(value)
|
||||
return self._term_query(value)
|
||||
|
||||
def _filter_exact(self, value, field, is_not):
|
||||
if ' ' in value:
|
||||
phrase_query = xapian.Query(
|
||||
xapian.Query.OP_PHRASE, [
|
||||
'%s%s%s' % (
|
||||
DOCUMENT_CUSTOM_TERM_PREFIX, field.upper(), _marshal_value(term)
|
||||
) for term in value.split()
|
||||
]
|
||||
)
|
||||
|
||||
if is_not:
|
||||
return xapian.Query(
|
||||
xapian.Query.OP_AND_NOT, xapian.Query(''), phrase_query
|
||||
xapian.Query.OP_AND_NOT, self._all_query(), self._phrase_query(value.split(), field)
|
||||
)
|
||||
else:
|
||||
return phrase_query
|
||||
return self._phrase_query(value.split(), field)
|
||||
else:
|
||||
term = '%s%s%s' % (
|
||||
DOCUMENT_CUSTOM_TERM_PREFIX, field.upper(), value
|
||||
)
|
||||
|
||||
if is_not:
|
||||
return xapian.Query(xapian.Query.OP_AND_NOT, '', term)
|
||||
return xapian.Query(xapian.Query.OP_AND_NOT, self._all_query(), self._term_query(value, field))
|
||||
else:
|
||||
return xapian.Query(term)
|
||||
|
||||
return self._term_query(value, field)
|
||||
|
||||
def _filter_in(self, value_list, field, is_not):
|
||||
query_list = []
|
||||
for value in value_list:
|
||||
if ' ' in value:
|
||||
query_list.append(
|
||||
xapian.Query(
|
||||
xapian.Query.OP_OR, self._phrase_query(value.split(), field)
|
||||
)
|
||||
)
|
||||
else:
|
||||
query_list.append(
|
||||
xapian.Query(
|
||||
xapian.Query.OP_OR, self._term_query(value, field)
|
||||
)
|
||||
)
|
||||
return xapian.Query(xapian.Query.OP_OR, query_list)
|
||||
|
||||
def _all_query(self):
|
||||
return xapian.Query('')
|
||||
|
||||
def _term_query(self, value, field=None):
|
||||
if field:
|
||||
return xapian.Query('%s%s%s' % (
|
||||
DOCUMENT_CUSTOM_TERM_PREFIX, field.upper(), _marshal_value(value)
|
||||
)
|
||||
)
|
||||
else:
|
||||
return xapian.Query(value)
|
||||
|
||||
def _phrase_query(self, value_list, field=None):
|
||||
if field:
|
||||
return xapian.Query(
|
||||
xapian.Query.OP_PHRASE, [
|
||||
'%s%s%s' % (
|
||||
DOCUMENT_CUSTOM_TERM_PREFIX, field.upper(), _marshal_value(value)
|
||||
) for value in value_list
|
||||
]
|
||||
)
|
||||
else:
|
||||
return xapian.Query(xapian.Query.OP_PHRASE, value_list)
|
||||
|
||||
|
||||
def _marshal_value(value):
|
||||
"""
|
||||
Private method that converts Python values to a string for Xapian values.
|
||||
Private utility method that converts Python values to a string for Xapian values.
|
||||
"""
|
||||
if isinstance(value, datetime.datetime):
|
||||
if value.microsecond:
|
||||
|
|
Loading…
Reference in New Issue