diff --git a/tests/xapian_tests/tests/xapian_query.py b/tests/xapian_tests/tests/xapian_query.py index 4bfde62..5d5e211 100644 --- a/tests/xapian_tests/tests/xapian_query.py +++ b/tests/xapian_tests/tests/xapian_query.py @@ -82,46 +82,39 @@ class XapianSearchQueryTestCase(TestCase): self.assertEqual(self.sq.build_query().get_description(), 'Xapian::Query((hello OR 5 * world))') # def test_build_query_multiple_filter_types(self): - # self.sq.add_filter('content', 'why') - # self.sq.add_filter('pub_date__lte', datetime.datetime(2009, 2, 10, 1, 59)) - # self.sq.add_filter('author__gt', 'david') - # self.sq.add_filter('created__lt', datetime.datetime(2009, 2, 12, 12, 13)) - # self.sq.add_filter('title__gte', 'B') - # self.sq.add_filter('id__in', [1, 2, 3]) - # self.assertEqual(self.sq.build_query(), 'why AND pub_date:..20090210015900 AND NOT author:..david AND NOT created:20090212121300..* AND title:B..* AND (id:1 OR id:2 OR id:3)') + # self.sq.add_filter(SQ(content='why')) + # self.sq.add_filter(SQ(pub_date__lte='2009-02-10 01:59:00')) + # self.sq.add_filter(SQ(author__gt='daniel')) + # self.sq.add_filter(SQ(created__lt='2009-02-12 12:13:00')) + # self.sq.add_filter(SQ(title__gte='B')) + # self.sq.add_filter(SQ(id__in=[1, 2, 3])) + # self.assertEqual(self.sq.build_query(), u'(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_multiple_exclude_types(self): - # self.sq.add_filter('content', 'why', use_not=True) - # self.sq.add_filter('pub_date__lte', datetime.datetime(2009, 2, 10, 1, 59), use_not=True) - # self.sq.add_filter('author__gt', 'david', use_not=True) - # self.sq.add_filter('created__lt', datetime.datetime(2009, 2, 12, 12, 13), use_not=True) - # self.sq.add_filter('title__gte', 'B', use_not=True) - # self.sq.add_filter('id__in', [1, 2, 3], use_not=True) - # self.assertEqual(self.sq.build_query(), 'NOT why AND NOT pub_date:..20090210015900 AND author:..david AND created:20090212121300..* AND NOT title:B..* AND NOT id:1 NOT id:2 NOT id:3') + # 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(), u'(why AND (title:"A Famous Paper" OR title:"An 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)])) + # self.assertEqual(self.sq.build_query(), u'(why AND (pub_date:"2009-07-06T01:56:21Z"))') # # def test_build_query_wildcard_filter_types(self): - # self.sq.add_filter('content', 'why') - # self.sq.add_filter('title__startswith', 'haystack') - # self.assertEqual(self.sq.build_query(), 'why AND title:haystack*') - # - # def test_clean(self): - # self.assertEqual(self.sq.clean('hello world'), 'hello world') - # self.assertEqual(self.sq.clean('hello AND world'), 'hello and world') - # self.assertEqual(self.sq.clean('hello AND OR NOT + - && || ! ( ) { } [ ] ^ " ~ * ? : \ world'), 'hello and or not \\+ \\- \\&& \\|| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\" \\~ \\* \\? \\: \\\\ world') - # self.assertEqual(self.sq.clean('so please NOTe i am in a bAND and bORed'), 'so please NOTe i am in a bAND and bORed') + # self.sq.add_filter(SQ(content='why')) + # self.sq.add_filter(SQ(title__startswith='haystack')) + # self.assertEqual(self.sq.build_query(), u'(why AND title:haystack*)') # + def test_clean(self): + self.assertEqual(self.sq.clean('hello world'), 'hello world') + self.assertEqual(self.sq.clean('hello AND world'), 'hello AND world') + self.assertEqual(self.sq.clean('hello AND OR NOT TO + - && || ! ( ) { } [ ] ^ " ~ * ? : \ world'), 'hello AND OR NOT TO + - && || ! ( ) { } [ ] ^ " ~ * ? : \ world') + self.assertEqual(self.sq.clean('so please NOTe i am in a bAND and bORed'), 'so please NOTe i am in a bAND and bORed') + # def test_build_query_with_models(self): - # self.sq.add_filter('content', 'hello') + # self.sq.add_filter(SQ(content='hello')) # self.sq.add_model(MockModel) - # self.assertEqual(self.sq.build_query(), u'(hello) django_ct:core.mockmodel') + # self.assertEqual(self.sq.build_query(), '(hello) AND (django_ct:core.mockmodel)') # # self.sq.add_model(AnotherMockModel) - # self.assertEqual(self.sq.build_query(), u'(hello) django_ct:core.anothermockmodel django_ct:core.mockmodel') - # - # def test_build_query_with_datetime(self): - # self.sq.add_filter('pub_date', datetime.datetime(2009, 5, 9, 16, 20)) - # self.assertEqual(self.sq.build_query(), u'pub_date:20090509162000') - # - # def test_build_query_with_sequence_and_filter_not_in(self): - # self.sq.add_filter('id__exact', [1, 2, 3]) - # self.assertEqual(self.sq.build_query(), u'id:[1, 2, 3]') + # self.assertEqual(self.sq.build_query(), '(hello) AND (django_ct:core.mockmodel OR django_ct:core.anothermockmodel)') diff --git a/xapian_backend.py b/xapian_backend.py index 039568e..5acd502 100755 --- a/xapian_backend.py +++ b/xapian_backend.py @@ -130,20 +130,6 @@ class SearchBackend(BaseSearchBackend): your settings. This should point to a location where you would your indexes to reside. """ - RESERVED_WORDS = ( - 'AND', - 'NOT', - 'OR', - 'XOR', - 'NEAR', - 'ADJ', - ) - - RESERVED_CHARACTERS = ( - '\\', '+', '-', '&&', '||', '!', '(', ')', '{', '}', - '[', ']', '^', '"', '~', '*', '?', ':', - ) - def __init__(self, site=None, stemming_language='english'): """ Instantiates an instance of `SearchBackend`. @@ -270,10 +256,9 @@ class SearchBackend(BaseSearchBackend): (model._meta.app_label, model._meta.module_name) ) @log_query - def search(self, query, sort_by=None, start_offset=0, - end_offset=0, fields='', highlight=False, - facets=None, date_facets=None, query_facets=None, - narrow_queries=None, boost=None, spelling_query=None, + def search(self, query, sort_by=None, start_offset=0, end_offset=None, + fields='', highlight=False, facets=None, date_facets=None, + query_facets=None, narrow_queries=None, spelling_query=None, limit_to_registered_models=True, **kwargs): """ Executes the search as defined in `query_string`. @@ -284,7 +269,7 @@ class SearchBackend(BaseSearchBackend): Optional arguments: `sort_by` -- Sort results by specified field (default = None) `start_offset` -- Slice results from `start_offset` (default = 0) - `end_offset` -- Slice results at `end_offset` (default = 0), if 0, then all documents + `end_offset` -- Slice results at `end_offset` (default = None), if None, then all documents `fields` -- Filter results on `fields` (default = '') `highlight` -- Highlight terms in results (default = False) `facets` -- Facet results on fields (default = None) @@ -292,7 +277,6 @@ class SearchBackend(BaseSearchBackend): `query_facets` -- Facet results on queries (default = None) `narrow_queries` -- Narrow queries (default = None) `spelling_query` -- An optional query to execute spelling suggestion on - `boost` -- Dictionary of terms and weights to boost results `limit_to_registered_models` -- Limit returned results to models registered in the current `SearchSite` (default = True) Returns: @@ -341,7 +325,7 @@ class SearchBackend(BaseSearchBackend): database = self._database() query, spelling_suggestion = self._query( - database, query_string, narrow_queries, spelling_query, boost + database, query_string, narrow_queries, spelling_query ) enquire = self._enquire(database, query) @@ -401,7 +385,7 @@ class SearchBackend(BaseSearchBackend): return self._database().get_doccount() def more_like_this(self, model_instance, additional_query_string=None, - start_offset=0, end_offset=0, + start_offset=0, end_offset=None, limit_to_registered_models=True, **kwargs): """ Given a model instance, returns a result set of similar documents. @@ -414,7 +398,7 @@ class SearchBackend(BaseSearchBackend): `additional_query_string` -- An additional query string to narrow results `start_offset` -- The starting offset (default=0) - `end_offset` -- The ending offset (default=0), if 0, then all documents + `end_offset` -- The ending offset (default=None), if None, then all documents `limit_to_registered_models` -- Limit returned results to models registered in the current `SearchSite` (default = True) Returns: @@ -721,7 +705,7 @@ class SearchBackend(BaseSearchBackend): term_generator.set_document(document) return term_generator - def _query(self, database, query_string, narrow_queries=None, spelling_query=None, boost=None): + def _query(self, database, query_string, narrow_queries=None, spelling_query=None): """ Private method that takes a query string and returns a xapian.Query. @@ -732,7 +716,6 @@ class SearchBackend(BaseSearchBackend): Optional arguments: `narrow_queries` -- A list of queries to narrow the query with `spelling_query` -- An optional query to execute spelling suggestion on - `boost` -- A dictionary of terms to boost with values Returns a xapian.Query instance with prefixes and ranges properly setup as pulled from the `query_string`. @@ -766,16 +749,6 @@ class SearchBackend(BaseSearchBackend): xapian.Query.OP_FILTER, query, xapian.Query(xapian.Query.OP_AND, subqueries) ) - if boost: - subqueries = [ - xapian.Query( - xapian.Query.OP_SCALE_WEIGHT, xapian.Query(term), value - ) for term, value in boost.iteritems() - ] - query = xapian.Query( - xapian.Query.OP_OR, query, - xapian.Query(xapian.Query.OP_AND, subqueries) - ) return query, spelling_suggestion