def setUp(self): super(XapianBoostBackendTestCase, self).setUp() self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = XapianBoostMockSearchIndex(AFourthMockModel, backend=self.sb) self.site.register(AFourthMockModel, XapianBoostMockSearchIndex) # Stow. import haystack self.old_site = haystack.site haystack.site = self.site self.sample_objs = [] for i in xrange(1, 5): mock = AFourthMockModel() mock.id = i if i % 2: mock.author = 'daniel' mock.editor = 'david' else: mock.author = 'david' mock.editor = 'daniel' mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) self.sample_objs.append(mock)
def test_log_query(self): backends.reset_search_queries() self.assertEqual(len(backends.queries), 0) # Stow. old_debug = settings.DEBUG settings.DEBUG = False len(self.sq.get_results()) self.assertEqual(len(backends.queries), 0) settings.DEBUG = True # Redefine it to clear out the cached results. self.sq = SearchQuery(backend=SearchBackend()) self.sq.add_filter(SQ(name='bar')) len(self.sq.get_results()) self.assertEqual(len(backends.queries), 1) self.assertEqual(str(backends.queries[0]['query_string']), u'Xapian::Query((ZXNAMEbar OR XNAMEbar))') # And again, for good measure. self.sq = SearchQuery(backend=SearchBackend()) self.sq.add_filter(SQ(name='bar')) self.sq.add_filter(SQ(text='moof')) len(self.sq.get_results()) self.assertEqual(len(backends.queries), 2) self.assertEqual(str(backends.queries[0]['query_string']), u'Xapian::Query((ZXNAMEbar OR XNAMEbar))') self.assertEqual( str(backends.queries[1]['query_string']), u'Xapian::Query(((ZXNAMEbar OR XNAMEbar) AND (ZXTEXTmoof OR XTEXTmoof)))' ) # Restore. settings.DEBUG = old_debug
def setUp(self): super(XapianSearchBackendTestCase, self).setUp() self.site = SearchSite() self.backend = SearchBackend(site=self.site) self.index = XapianMockSearchIndex(XapianMockModel, backend=self.backend) self.site.register(XapianMockModel, XapianMockSearchIndex) self.sample_objs = [] for i in xrange(1, 4): mock = XapianMockModel() mock.id = i mock.author = 'david%s' % i mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) mock.exp_date = datetime.date(2009, 2, 23) + datetime.timedelta(days=i) mock.value = i * 5 mock.flag = bool(i % 2) mock.slug = 'http://example.com/%d/' % i mock.url = 'http://example.com/%d/' % i self.sample_objs.append(mock) self.sample_objs[0].popularity = 834.0 self.sample_objs[1].popularity = 35.5 self.sample_objs[2].popularity = 972.0
def setUp(self): super(LiveXapianSearchQueryTestCase, self).setUp() site = SearchSite() backend = SearchBackend(site=site) index = LiveXapianMockSearchIndex(MockModel, backend=backend) site.register(MockModel, LiveXapianMockSearchIndex) backend.update(index, MockModel.objects.all()) self.sq = SearchQuery(backend=backend)
def setUp(self): super(LiveXapianAutocompleteTestCase, self).setUp() site = SearchSite() backend = SearchBackend(site=site) index = XapianAutocompleteMockModelSearchIndex(MockModel, backend=backend) site.register(MockModel, XapianAutocompleteMockModelSearchIndex) backend.update(index, MockModel.objects.all()) self.sq = SearchQuery(backend=backend) self.sqs = SearchQuerySet(query=self.sq)
class XapianBoostBackendTestCase(TestCase): def setUp(self): super(XapianBoostBackendTestCase, self).setUp() self.site = SearchSite() self.sb = SearchBackend(site=self.site) self.smmi = XapianBoostMockSearchIndex(AFourthMockModel, backend=self.sb) self.site.register(AFourthMockModel, XapianBoostMockSearchIndex) # Stow. import haystack self.old_site = haystack.site haystack.site = self.site self.sample_objs = [] for i in xrange(1, 5): mock = AFourthMockModel() mock.id = i if i % 2: mock.author = 'daniel' mock.editor = 'david' else: mock.author = 'david' mock.editor = 'daniel' mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) self.sample_objs.append(mock) def tearDown(self): import haystack haystack.site = self.old_site super(XapianBoostBackendTestCase, self).tearDown() def test_boost(self): self.sb.update(self.smmi, self.sample_objs) sqs = SearchQuerySet() self.assertEqual(len(sqs.all()), 4) results = sqs.filter(SQ(author='daniel') | SQ(editor='daniel')) self.assertEqual([result.id for result in results], [ 'core.afourthmockmodel.1', 'core.afourthmockmodel.3', 'core.afourthmockmodel.2', 'core.afourthmockmodel.4' ])
def setUp(self): super(XapianSearchBackendTestCase, self).setUp() temp_path = os.path.join('tmp', 'test_xapian_query') self.old_xapian_path = getattr(settings, 'HAYSTACK_XAPIAN_PATH', temp_path) settings.HAYSTACK_XAPIAN_PATH = temp_path self.site = XapianSearchSite() self.sb = SearchBackend(site=self.site) self.msi = XapianMockSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, XapianMockSearchIndex) self.sample_objs = [] for i in xrange(1, 4): mock = MockModel() mock.id = i mock.author = 'david%s' % i mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) mock.value = i * 5 mock.flag = bool(i % 2) mock.slug = 'http://example.com/%d' % i self.sample_objs.append(mock) self.sample_objs[0].popularity = 834.0 self.sample_objs[1].popularity = 35.0 self.sample_objs[2].popularity = 972.0
class XapianSearchBackendTestCase(TestCase): def setUp(self): super(XapianSearchBackendTestCase, self).setUp() self.site = SearchSite() self.backend = SearchBackend(site=self.site) self.index = XapianMockSearchIndex(XapianMockModel, backend=self.backend) self.site.register(XapianMockModel, XapianMockSearchIndex) self.sample_objs = [] for i in xrange(1, 4): mock = XapianMockModel() mock.id = i mock.author = 'david%s' % i mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) mock.value = i * 5 mock.flag = bool(i % 2) mock.slug = 'http://example.com/%d/' % i mock.url = 'http://example.com/%d/' % i self.sample_objs.append(mock) self.sample_objs[0].popularity = 834.0 self.sample_objs[1].popularity = 35.5 self.sample_objs[2].popularity = 972.0 def tearDown(self): if os.path.exists(settings.HAYSTACK_XAPIAN_PATH): shutil.rmtree(settings.HAYSTACK_XAPIAN_PATH) super(XapianSearchBackendTestCase, self).tearDown() def test_update(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3]) def test_duplicate_update(self): self.backend.update(self.index, self.sample_objs) self.backend.update(self.index, self.sample_objs) # Duplicates should be updated, not appended -- http://github.com/notanumber/xapian-haystack/issues/#issue/6 self.assertEqual(self.backend.document_count(), 3) def test_remove(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.backend.remove(self.sample_objs[0]) self.assertEqual(self.backend.document_count(), 2) self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [2, 3]) def test_clear(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.backend.clear() self.assertEqual(self.backend.document_count(), 0) self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.backend.clear([AnotherMockModel]) self.assertEqual(self.backend.document_count(), 3) self.backend.clear([XapianMockModel]) self.assertEqual(self.backend.document_count(), 0) self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.backend.clear([AnotherMockModel, XapianMockModel]) self.assertEqual(self.backend.document_count(), 0) def test_search(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.assertEqual(self.backend.search(xapian.Query()), {'hits': 0, 'results': []}) self.assertEqual(self.backend.search(xapian.Query(''))['hits'], 3) self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3]) self.assertEqual(self.backend.search(xapian.Query('indexed'))['hits'], 3) self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3]) def test_search_field_with_punctuation(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) # self.assertEqual(self.backend.search(xapian.Query('http://example.com/'))['hits'], 3) self.assertEqual([result.pk for result in self.backend.search(xapian.Query('http://example.com/1/'))['results']], [1]) def test_search_by_mvf(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.assertEqual(self.backend.search(xapian.Query('ab'))['hits'], 1) self.assertEqual(self.backend.search(xapian.Query('b'))['hits'], 1) self.assertEqual(self.backend.search(xapian.Query('to'))['hits'], 1) self.assertEqual(self.backend.search(xapian.Query('one'))['hits'], 3) def test_field_facets(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.assertEqual(self.backend.search(xapian.Query(), facets=['name']), {'hits': 0, 'results': []}) results = self.backend.search(xapian.Query('indexed'), facets=['name']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['name'], [('david1', 1), ('david2', 1), ('david3', 1)]) results = self.backend.search(xapian.Query('indexed'), facets=['flag']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['flag'], [(False, 1), (True, 2)]) results = self.backend.search(xapian.Query('indexed'), facets=['sites']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['sites'], [('1', 1), ('3', 2), ('2', 2), ('4', 1), ('6', 2), ('9', 1)]) def test_date_facets(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.assertEqual(self.backend.search(xapian.Query(), date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}}), {'hits': 0, 'results': []}) results = self.backend.search(xapian.Query('indexed'), date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}}) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['dates']['pub_date'], [ ('2009-02-26T00:00:00', 0), ('2009-01-26T00:00:00', 3), ('2008-12-26T00:00:00', 0), ('2008-11-26T00:00:00', 0), ('2008-10-26T00:00:00', 0), ]) results = self.backend.search(xapian.Query('indexed'), date_facets={'pub_date': {'start_date': datetime.datetime(2009, 02, 01), 'end_date': datetime.datetime(2009, 3, 15), 'gap_by': 'day', 'gap_amount': 15}})
class XapianSearchBackendTestCase(TestCase): def setUp(self): super(XapianSearchBackendTestCase, self).setUp() self.site = SearchSite() self.backend = SearchBackend(site=self.site) self.index = XapianMockSearchIndex(XapianMockModel, backend=self.backend) self.site.register(XapianMockModel, XapianMockSearchIndex) self.sample_objs = [] for i in xrange(1, 4): mock = XapianMockModel() mock.id = i mock.author = 'david%s' % i mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) mock.value = i * 5 mock.flag = bool(i % 2) mock.slug = 'http://example.com/%d/' % i mock.url = 'http://example.com/%d/' % i self.sample_objs.append(mock) self.sample_objs[0].popularity = 834.0 self.sample_objs[1].popularity = 35.5 self.sample_objs[2].popularity = 972.0 def tearDown(self): if os.path.exists(settings.HAYSTACK_XAPIAN_PATH): shutil.rmtree(settings.HAYSTACK_XAPIAN_PATH) super(XapianSearchBackendTestCase, self).tearDown() def xapian_search(self, query_string): database = xapian.Database(settings.HAYSTACK_XAPIAN_PATH) if query_string: qp = xapian.QueryParser() qp.set_database(database) query = qp.parse_query(query_string, xapian.QueryParser.FLAG_WILDCARD) else: query = xapian.Query(query_string) # Empty query matches all enquire = xapian.Enquire(database) enquire.set_query(query) matches = enquire.get_mset(0, database.get_doccount()) document_list = [] for match in matches: app_label, module_name, pk, model_data = pickle.loads(match.document.get_data()) for key, value in model_data.iteritems(): model_data[key] = _marshal_value(value) model_data['id'] = u'%s.%s.%d' % (app_label, module_name, pk) document_list.append(model_data) return document_list def test_update(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual([dict(doc) for doc in self.xapian_search('')], [ {'flag': u't', 'name': u'david1', 'name_exact': u'david1', 'tags': u"['a', 'b', 'c']", 'keys': u'[1, 2, 3]', 'text': u'indexed!\n1', 'sites': u"['1', '2', '3']", 'titles': u"['object one title one', 'object one title two']", 'pub_date': u'20090224000000', 'value': u'000000000005', 'month': u'02', 'id': u'tests.xapianmockmodel.1', 'slug': u'http://example.com/1/', 'url': u'http://example.com/1/', 'popularity': '\xca\x84', 'django_id': u'1', 'django_ct': u'tests.xapianmockmodel', 'empty': u''}, {'flag': u'f', 'name': u'david2', 'name_exact': u'david2', 'tags': u"['ab', 'bc', 'cd']", 'keys': u'[2, 4, 6]', 'text': u'indexed!\n2', 'sites': u"['2', '4', '6']", 'titles': u"['object two title one', 'object two title two']", 'pub_date': u'20090223000000', 'value': u'000000000010', 'month': u'02', 'id': u'tests.xapianmockmodel.2', 'slug': u'http://example.com/2/', 'url': u'http://example.com/2/', 'popularity': '\xb4p', 'django_id': u'2', 'django_ct': u'tests.xapianmockmodel', 'empty': u''}, {'flag': u't', 'name': u'david3', 'name_exact': u'david3', 'tags': u"['an', 'to', 'or']", 'keys': u'[3, 6, 9]', 'text': u'indexed!\n3', 'sites': u"['3', '6', '9']", 'titles': u"['object three title one', 'object three title two']", 'pub_date': u'20090222000000', 'value': u'000000000015', 'month': u'02', 'id': u'tests.xapianmockmodel.3', 'slug': u'http://example.com/3/', 'url': u'http://example.com/3/', 'popularity': '\xcb\x98', 'django_id': u'3', 'django_ct': u'tests.xapianmockmodel', 'empty': u''} ]) def test_duplicate_update(self): self.backend.update(self.index, self.sample_objs) self.backend.update(self.index, self.sample_objs) # Duplicates should be updated, not appended -- http://github.com/notanumber/xapian-haystack/issues/#issue/6 self.assertEqual(len(self.xapian_search('')), 3) def test_remove(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.backend.remove(self.sample_objs[0]) self.assertEqual(len(self.xapian_search('')), 2) self.assertEqual([dict(doc) for doc in self.xapian_search('')], [ {'flag': u'f', 'name': u'david2', 'name_exact': u'david2', 'tags': u"['ab', 'bc', 'cd']", 'keys': u'[2, 4, 6]', 'text': u'indexed!\n2', 'sites': u"['2', '4', '6']", 'titles': u"['object two title one', 'object two title two']", 'pub_date': u'20090223000000', 'value': u'000000000010', 'month': u'02', 'id': u'tests.xapianmockmodel.2', 'slug': u'http://example.com/2/', 'url': u'http://example.com/2/', 'popularity': '\xb4p', 'django_id': u'2', 'django_ct': u'tests.xapianmockmodel', 'empty': u''}, {'flag': u't', 'name': u'david3', 'name_exact': u'david3', 'tags': u"['an', 'to', 'or']", 'keys': u'[3, 6, 9]', 'text': u'indexed!\n3', 'sites': u"['3', '6', '9']", 'titles': u"['object three title one', 'object three title two']", 'pub_date': u'20090222000000', 'value': u'000000000015', 'month': u'02', 'id': u'tests.xapianmockmodel.3', 'slug': u'http://example.com/3/', 'url': u'http://example.com/3/', 'popularity': '\xcb\x98', 'django_id': u'3', 'django_ct': u'tests.xapianmockmodel', 'empty': u''} ]) def test_clear(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.backend.clear() self.assertEqual(len(self.xapian_search('')), 0) self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.backend.clear([AnotherMockModel]) self.assertEqual(len(self.xapian_search('')), 3) self.backend.clear([XapianMockModel]) self.assertEqual(len(self.xapian_search('')), 0) self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.backend.clear([AnotherMockModel, XapianMockModel]) self.assertEqual(len(self.xapian_search('')), 0) def test_search(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual(self.backend.search(xapian.Query()), {'hits': 0, 'results': []}) self.assertEqual(self.backend.search(xapian.Query(''))['hits'], 3) self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3]) self.assertEqual(self.backend.search(xapian.Query('indexed'))['hits'], 3) self.assertEqual([result.pk for result in self.backend.search(xapian.Query(''))['results']], [1, 2, 3]) def test_search_field_with_punctuation(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) # self.assertEqual(self.backend.search(xapian.Query('http://example.com/'))['hits'], 3) self.assertEqual([result.pk for result in self.backend.search(xapian.Query('http://example.com/1/'))['results']], [1]) def test_search_by_mvf(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual(self.backend.search(xapian.Query('ab'))['hits'], 1) self.assertEqual(self.backend.search(xapian.Query('b'))['hits'], 1) self.assertEqual(self.backend.search(xapian.Query('to'))['hits'], 1) self.assertEqual(self.backend.search(xapian.Query('one'))['hits'], 3) def test_field_facets(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual(self.backend.search(xapian.Query(), facets=['name']), {'hits': 0, 'results': []}) results = self.backend.search(xapian.Query('indexed'), facets=['name']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['name'], [('david1', 1), ('david2', 1), ('david3', 1)]) results = self.backend.search(xapian.Query('indexed'), facets=['flag']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['flag'], [(False, 1), (True, 2)]) results = self.backend.search(xapian.Query('indexed'), facets=['sites']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['sites'], [('1', 1), ('3', 2), ('2', 2), ('4', 1), ('6', 2), ('9', 1)]) def test_date_facets(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual(self.backend.search(xapian.Query(), date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}}), {'hits': 0, 'results': []}) results = self.backend.search(xapian.Query('indexed'), date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}}) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['dates']['pub_date'], [ ('2009-02-26T00:00:00', 0), ('2009-01-26T00:00:00', 3), ('2008-12-26T00:00:00', 0), ('2008-11-26T00:00:00', 0), ('2008-10-26T00:00:00', 0), ]) results = self.backend.search(xapian.Query('indexed'), date_facets={'pub_date': {'start_date': datetime.datetime(2009, 02, 01), 'end_date': datetime.datetime(2009, 3, 15), 'gap_by': 'day', 'gap_amount': 15}})
def setUp(self): super(XapianSearchQueryTestCase, self).setUp() self.sq = SearchQuery(backend=SearchBackend())
class XapianSearchBackendTestCase(TestCase): def setUp(self): super(XapianSearchBackendTestCase, self).setUp() self.site = SearchSite() self.backend = SearchBackend(site=self.site) self.index = XapianMockSearchIndex(XapianMockModel, backend=self.backend) self.site.register(XapianMockModel, XapianMockSearchIndex) self.sample_objs = [] for i in xrange(1, 4): mock = XapianMockModel() mock.id = i mock.author = 'david%s' % i mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) mock.exp_date = datetime.date(2009, 2, 23) + datetime.timedelta(days=i) mock.value = i * 5 mock.flag = bool(i % 2) mock.slug = 'http://example.com/%d/' % i mock.url = 'http://example.com/%d/' % i self.sample_objs.append(mock) self.sample_objs[0].popularity = 834.0 self.sample_objs[1].popularity = 35.5 self.sample_objs[2].popularity = 972.0 def tearDown(self): if os.path.exists(settings.HAYSTACK_XAPIAN_PATH): shutil.rmtree(settings.HAYSTACK_XAPIAN_PATH) super(XapianSearchBackendTestCase, self).tearDown() def test_update(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.assertEqual([ result.pk for result in self.backend.search(xapian.Query(''))['results'] ], [1, 2, 3]) def test_duplicate_update(self): self.backend.update(self.index, self.sample_objs) self.backend.update( self.index, self.sample_objs ) # Duplicates should be updated, not appended -- http://github.com/notanumber/xapian-haystack/issues/#issue/6 self.assertEqual(self.backend.document_count(), 3) def test_remove(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.backend.remove(self.sample_objs[0]) self.assertEqual(self.backend.document_count(), 2) self.assertEqual([ result.pk for result in self.backend.search(xapian.Query(''))['results'] ], [2, 3]) def test_clear(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.backend.clear() self.assertEqual(self.backend.document_count(), 0) self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.backend.clear([AnotherMockModel]) self.assertEqual(self.backend.document_count(), 3) self.backend.clear([XapianMockModel]) self.assertEqual(self.backend.document_count(), 0) self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.backend.clear([AnotherMockModel, XapianMockModel]) self.assertEqual(self.backend.document_count(), 0) def test_search(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.assertEqual(self.backend.search(xapian.Query()), { 'hits': 0, 'results': [] }) self.assertEqual(self.backend.search(xapian.Query(''))['hits'], 3) self.assertEqual([ result.pk for result in self.backend.search(xapian.Query(''))['results'] ], [1, 2, 3]) self.assertEqual( self.backend.search(xapian.Query('indexed'))['hits'], 3) self.assertEqual([ result.pk for result in self.backend.search(xapian.Query(''))['results'] ], [1, 2, 3]) # Ensure that swapping the ``result_class`` works. self.assertTrue( isinstance( self.backend.search( xapian.Query('indexed'), result_class=MockSearchResult)['results'][0], MockSearchResult)) def test_search_field_with_punctuation(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) # self.assertEqual(self.backend.search(xapian.Query('http://example.com/'))['hits'], 3) self.assertEqual([ result.pk for result in self.backend.search( xapian.Query('http://example.com/1/'))['results'] ], [1]) def test_search_by_mvf(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.assertEqual(self.backend.search(xapian.Query('ab'))['hits'], 1) self.assertEqual(self.backend.search(xapian.Query('b'))['hits'], 1) self.assertEqual(self.backend.search(xapian.Query('to'))['hits'], 1) self.assertEqual(self.backend.search(xapian.Query('one'))['hits'], 3) def test_field_facets(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.assertEqual(self.backend.search(xapian.Query(), facets=['name']), { 'hits': 0, 'results': [] }) results = self.backend.search(xapian.Query('indexed'), facets=['name']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['name'], [('david1', 1), ('david2', 1), ('david3', 1)]) results = self.backend.search(xapian.Query('indexed'), facets=['flag']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['flag'], [(False, 1), (True, 2)]) results = self.backend.search(xapian.Query('indexed'), facets=['sites']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['sites'], [('1', 1), ('3', 2), ('2', 2), ('4', 1), ('6', 2), ('9', 1)]) def test_date_facets(self): self.backend.update(self.index, self.sample_objs) self.assertEqual(self.backend.document_count(), 3) self.assertEqual( self.backend.search(xapian.Query(), date_facets={ 'pub_date': { 'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month' } }), { 'hits': 0, 'results': [] }) results = self.backend.search(xapian.Query('indexed'), date_facets={ 'pub_date': { 'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month' } }) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['dates']['pub_date'], [ ('2009-02-26T00:00:00', 0), ('2009-01-26T00:00:00', 3), ('2008-12-26T00:00:00', 0), ('2008-11-26T00:00:00', 0), ('2008-10-26T00:00:00', 0), ]) results = self.backend.search(xapian.Query('indexed'), date_facets={ 'pub_date': { 'start_date': datetime.datetime(2009, 02, 01), 'end_date': datetime.datetime(2009, 3, 15), 'gap_by': 'day', 'gap_amount': 15 } })
class XapianSearchBackendTestCase(TestCase): def setUp(self): super(XapianSearchBackendTestCase, self).setUp() temp_path = os.path.join('tmp', 'test_xapian_query') self.old_xapian_path = getattr(settings, 'HAYSTACK_XAPIAN_PATH', temp_path) settings.HAYSTACK_XAPIAN_PATH = temp_path self.site = XapianSearchSite() self.sb = SearchBackend(site=self.site) self.msi = XapianMockSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, XapianMockSearchIndex) self.sample_objs = [] for i in xrange(1, 4): mock = MockModel() mock.id = i mock.author = 'david%s' % i mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) mock.value = i * 5 mock.flag = bool(i % 2) mock.slug = 'http://example.com/%d' % i self.sample_objs.append(mock) self.sample_objs[0].popularity = 834.0 self.sample_objs[1].popularity = 35.0 self.sample_objs[2].popularity = 972.0 def tearDown(self): if os.path.exists(settings.HAYSTACK_XAPIAN_PATH): shutil.rmtree(settings.HAYSTACK_XAPIAN_PATH) settings.HAYSTACK_XAPIAN_PATH = self.old_xapian_path super(XapianSearchBackendTestCase, self).tearDown() def xapian_search(self, query_string): database = xapian.Database(settings.HAYSTACK_XAPIAN_PATH) if query_string: qp = xapian.QueryParser() qp.set_database(database) query = qp.parse_query(query_string, xapian.QueryParser.FLAG_WILDCARD) else: query = xapian.Query(query_string) # Empty query matches all enquire = xapian.Enquire(database) enquire.set_query(query) matches = enquire.get_mset(0, DEFAULT_MAX_RESULTS) document_list = [] for match in matches: document = match.get_document() app_label, module_name, pk, model_data = pickle.loads(document.get_data()) for key, value in model_data.iteritems(): model_data[key] = self.sb._marshal_value(value) model_data['id'] = u'%s.%s.%d' % (app_label, module_name, pk) document_list.append(model_data) return document_list def test_update(self): self.sb.update(self.msi, self.sample_objs) self.sb.update(self.msi, self.sample_objs) # Duplicates should be updated, not appended -- http://github.com/notanumber/xapian-haystack/issues/#issue/6 self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual([dict(doc) for doc in self.xapian_search('')], [ {'flag': u't', 'name': u'david1', 'text': u'Indexed!\n1', 'sites': u"['1', '2', '3']", 'pub_date': u'20090224000000', 'value': '000000000005', 'id': u'core.mockmodel.1', 'slug': 'http://example.com/1', 'popularity': '\xca\x84'}, {'flag': u'f', 'name': u'david2', 'text': u'Indexed!\n2', 'sites': u"['2', '4', '6']", 'pub_date': u'20090223000000', 'value': '000000000010', 'id': u'core.mockmodel.2', 'slug': 'http://example.com/2', 'popularity': '\xb4`'}, {'flag': u't', 'name': u'david3', 'text': u'Indexed!\n3', 'sites': u"['3', '6', '9']", 'pub_date': u'20090222000000', 'value': '000000000015', 'id': u'core.mockmodel.3', 'slug': 'http://example.com/3', 'popularity': '\xcb\x98'} ]) def test_remove(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.sb.remove(self.sample_objs[0]) self.assertEqual(len(self.xapian_search('')), 2) self.assertEqual([dict(doc) for doc in self.xapian_search('')], [ {'flag': u'f', 'name': u'david2', 'text': u'Indexed!\n2', 'sites': u"['2', '4', '6']", 'pub_date': u'20090223000000', 'value': '000000000010', 'id': u'core.mockmodel.2', 'slug': 'http://example.com/2', 'popularity': '\xb4`'}, {'flag': u't', 'name': u'david3', 'text': u'Indexed!\n3', 'sites': u"['3', '6', '9']", 'pub_date': u'20090222000000', 'value': '000000000015', 'id': u'core.mockmodel.3', 'slug': 'http://example.com/3', 'popularity': '\xcb\x98'} ]) def test_clear(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.sb.clear() self.assertEqual(len(self.xapian_search('')), 0) self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.sb.clear([AnotherMockModel]) self.assertEqual(len(self.xapian_search('')), 3) self.sb.clear([MockModel]) self.assertEqual(len(self.xapian_search('')), 0) self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.sb.clear([AnotherMockModel, MockModel]) self.assertEqual(len(self.xapian_search('')), 0) def test_search(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) # Empty query self.assertEqual(self.sb.search(''), {'hits': 0, 'results': []}) # Wildcard -- All self.assertEqual(self.sb.search('*')['hits'], 3) self.assertEqual([result.pk for result in self.sb.search('*')['results']], [1, 2, 3]) # NOT operator self.assertEqual([result.pk for result in self.sb.search('NOT name:david1')['results']], [2, 3]) self.assertEqual([result.pk for result in self.sb.search('NOT name:david1 AND index')['results']], [2, 3]) self.assertEqual([result.pk for result in self.sb.search('index NOT name:david1')['results']], [2, 3]) self.assertEqual([result.pk for result in self.sb.search('index NOT name:david1 NOT name:david2')['results']], [3]) self.assertEqual([result.pk for result in self.sb.search('NOT name:david1 NOT name:david2')['results']], [3]) # Ranges self.assertEqual([result.pk for result in self.sb.search('index name:david2..david3')['results']], [2, 3]) self.assertEqual([result.pk for result in self.sb.search('index name:..david2')['results']], [1, 2]) self.assertEqual([result.pk for result in self.sb.search('index name:david2..*')['results']], [2, 3]) self.assertEqual([result.pk for result in self.sb.search('index pub_date:20090222000000..20090223000000')['results']], [2, 3]) self.assertEqual([result.pk for result in self.sb.search('index pub_date:..20090223000000')['results']], [2, 3]) self.assertEqual([result.pk for result in self.sb.search('index pub_date:20090223000000..*')['results']], [1, 2]) self.assertEqual([result.pk for result in self.sb.search('index value:10..15')['results']], [2, 3]) self.assertEqual([result.pk for result in self.sb.search('index value:..10')['results']], [1, 2]) self.assertEqual([result.pk for result in self.sb.search('index value:10..*')['results']], [2, 3]) self.assertEqual([result.pk for result in self.sb.search('index popularity:..100.0')['results']], [2]) self.assertEqual([result.pk for result in self.sb.search('index popularity:100.0..*')['results']], [1, 3]) def test_field_facets(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual(self.sb.search('', facets=['name']), {'hits': 0, 'results': []}) results = self.sb.search('index', facets=['name']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['name'], [('david1', 1), ('david2', 1), ('david3', 1)]) results = self.sb.search('index', facets=['flag']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['flag'], [(False, 1), (True, 2)]) results = self.sb.search('index', facets=['sites']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['sites'], [('1', 1), ('3', 2), ('2', 2), ('4', 1), ('6', 2), ('9', 1)]) def test_date_facets(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual(self.sb.search('', date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}}), {'hits': 0, 'results': []}) results = self.sb.search('index', date_facets={'pub_date': {'start_date': datetime.datetime(2008, 10, 26), 'end_date': datetime.datetime(2009, 3, 26), 'gap_by': 'month'}}) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['dates']['pub_date'], [ ('2009-02-26T00:00:00', 0), ('2009-01-26T00:00:00', 3), ('2008-12-26T00:00:00', 0), ('2008-11-26T00:00:00', 0), ('2008-10-26T00:00:00', 0), ]) results = self.sb.search('index', date_facets={'pub_date': {'start_date': datetime.datetime(2009, 02, 01), 'end_date': datetime.datetime(2009, 3, 15), 'gap_by': 'day', 'gap_amount': 15}})
class XapianSearchBackendTestCase(TestCase): def setUp(self): super(XapianSearchBackendTestCase, self).setUp() temp_path = os.path.join('tmp', 'test_xapian_query') self.old_xapian_path = getattr(settings, 'HAYSTACK_XAPIAN_PATH', temp_path) settings.HAYSTACK_XAPIAN_PATH = temp_path self.site = XapianSearchSite() self.sb = SearchBackend(site=self.site) self.msi = XapianMockSearchIndex(MockModel, backend=self.sb) self.site.register(MockModel, XapianMockSearchIndex) self.sample_objs = [] for i in xrange(1, 4): mock = MockModel() mock.id = i mock.author = 'david%s' % i mock.pub_date = datetime.date(2009, 2, 25) - datetime.timedelta(days=i) mock.value = i * 5 mock.flag = bool(i % 2) self.sample_objs.append(mock) def tearDown(self): if os.path.exists(settings.HAYSTACK_XAPIAN_PATH): index_files = os.listdir(settings.HAYSTACK_XAPIAN_PATH) for index_file in index_files: os.remove(os.path.join(settings.HAYSTACK_XAPIAN_PATH, index_file)) os.removedirs(settings.HAYSTACK_XAPIAN_PATH) settings.HAYSTACK_XAPIAN_PATH = self.old_xapian_path super(XapianSearchBackendTestCase, self).tearDown() def xapian_search(self, query_string): database = xapian.Database(settings.HAYSTACK_XAPIAN_PATH) if query_string: qp = xapian.QueryParser() qp.set_database(database) query = qp.parse_query(query_string, xapian.QueryParser.FLAG_WILDCARD) else: query = xapian.Query(query_string) # Empty query matches all enquire = xapian.Enquire(database) enquire.set_query(query) matches = enquire.get_mset(0, DEFAULT_MAX_RESULTS) document_list = [] for match in matches: document = match.get_document() object_data = pickle.loads(document.get_data()) for key, value in object_data.iteritems(): object_data[key] = self.sb._from_python(value) object_data['id'] = force_unicode(document.get_value(0)) document_list.append(object_data) return document_list def test_update(self): self.sb.update(self.msi, self.sample_objs) self.sb.update(self.msi, self.sample_objs) # Duplicates should be updated, not appended -- http://github.com/notanumber/xapian-haystack/issues/#issue/6 self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual([dict(doc) for doc in self.xapian_search('')], [{'flag': u'true', 'name': u'david1', 'text': u'Indexed!\n1', 'pub_date': u'2009-02-24T00:00:00', 'value': u'5', 'id': u'tests.mockmodel.1'}, {'flag': u'false', 'name': u'david2', 'text': u'Indexed!\n2', 'pub_date': u'2009-02-23T00:00:00', 'value': u'10', 'id': u'tests.mockmodel.2'}, {'flag': u'true', 'name': u'david3', 'text': u'Indexed!\n3', 'pub_date': u'2009-02-22T00:00:00', 'value': u'15', 'id': u'tests.mockmodel.3'}]) def test_remove(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.sb.remove(self.sample_objs[0]) self.assertEqual(len(self.xapian_search('')), 2) self.assertEqual([dict(doc) for doc in self.xapian_search('')], [{'flag': u'false', 'name': u'david2', 'text': u'Indexed!\n2', 'pub_date': u'2009-02-23T00:00:00', 'value': u'10', 'id': u'tests.mockmodel.2'}, {'flag': u'true', 'name': u'david3', 'text': u'Indexed!\n3', 'pub_date': u'2009-02-22T00:00:00', 'value': u'15', 'id': u'tests.mockmodel.3'}]) def test_clear(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.sb.clear() self.assertEqual(len(self.xapian_search('')), 0) self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.sb.clear([AnotherMockModel]) self.assertEqual(len(self.xapian_search('')), 3) self.sb.clear([MockModel]) self.assertEqual(len(self.xapian_search('')), 0) self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.sb.clear([AnotherMockModel, MockModel]) self.assertEqual(len(self.xapian_search('')), 0) def test_search(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual(self.sb.search(''), {'hits': 0, 'results': []}) self.assertEqual(self.sb.search('*')['hits'], 3) self.assertEqual([result.pk for result in self.sb.search('*')['results']], [u'1', u'2', u'3']) # self.assertEqual(self.sb.search('', highlight=True), {'hits': 0, 'results': []}) # self.assertEqual(self.sb.search('Index*', highlight=True)['hits'], 3) # self.assertEqual([result.highlighted['text'][0] for result in self.sb.search('Index*', highlight=True)['results']], ['<em>Indexed</em>!\n3', '<em>Indexed</em>!\n2', '<em>Indexed</em>!\n1']) # self.assertEqual(self.sb.search('', facets=['name']), {'hits': 0, 'results': []}) results = self.sb.search('index', facets=['name']) self.assertEqual(results['hits'], 3) self.assertEqual(results['facets']['fields']['name'], [('david1', 1), ('david2', 1), ('david3', 1)]) # self.assertEqual(self.sb.search('', date_facets={'pub_date': {'start_date': datetime.date(2008, 2, 26), 'end_date': datetime.date(2008, 2, 26), 'gap': '/MONTH'}}), []) # results = self.sb.search('Index*', date_facets={'pub_date': {'start_date': datetime.date(2008, 2, 26), 'end_date': datetime.date(2008, 2, 26), 'gap': '/MONTH'}}) # self.assertEqual(results['hits'], 3) # self.assertEqual(results['facets'], {}) # # self.assertEqual(self.sb.search('', query_facets={'name': '[* TO e]'}), []) # results = self.sb.search('Index*', query_facets={'name': '[* TO e]'}) # self.assertEqual(results['hits'], 3) # self.assertEqual(results['facets'], {}) self.assertEqual(self.sb.search('', narrow_queries=['name:david1']), {'hits': 0, 'results': []}) results = self.sb.search('index*', narrow_queries=['name:david1']) self.assertEqual(results['hits'], 1) def test_spelling_suggestion(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) self.assertEqual(self.sb.search('indxe')['hits'], 0) self.assertEqual(self.sb.search('indxe')['spelling_suggestion'], 'indexed') self.assertEqual(self.sb.search('indxed')['hits'], 0) self.assertEqual(self.sb.search('indxed')['spelling_suggestion'], 'indexed') def test_stemming(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) results = self.sb.search('index', facets=['name']) self.assertEqual(results['hits'], 3) results = self.sb.search('indexing', facets=['name']) self.assertEqual(results['hits'], 3) def test_more_like_this(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(len(self.xapian_search('')), 3) results = self.sb.more_like_this(self.sample_objs[0]) self.assertEqual(results['hits'], 2) self.assertEqual([result.pk for result in results['results']], [u'3', u'2']) def test_document_count(self): self.sb.update(self.msi, self.sample_objs) self.assertEqual(self.sb.document_count(), 3) def test_delete_index(self): self.sb.update(self.msi, self.sample_objs) self.assert_(self.sb.document_count() > 0) self.sb.delete_index() self.assertEqual(self.sb.document_count(), 0) def test_order_by(self): self.sb.update(self.msi, self.sample_objs) results = self.sb.search('*', sort_by=['pub_date']) self.assertEqual([result.pk for result in results['results']], [u'1', u'2', u'3']) results = self.sb.search('*', sort_by=['-pub_date']) self.assertEqual([result.pk for result in results['results']], [u'3', u'2', u'1']) results = self.sb.search('*', sort_by=['id']) self.assertEqual([result.pk for result in results['results']], [u'3', u'2', u'1']) results = self.sb.search('*', sort_by=['-id']) self.assertEqual([result.pk for result in results['results']], [u'1', u'2', u'3']) results = self.sb.search('*', sort_by=['value']) self.assertEqual([result.pk for result in results['results']], [u'3', u'2', u'1']) results = self.sb.search('*', sort_by=['-value']) self.assertEqual([result.pk for result in results['results']], [u'1', u'2', u'3']) results = self.sb.search('*', sort_by=['flag', 'id']) self.assertEqual([result.pk for result in results['results']], [u'3', u'1', u'2']) results = self.sb.search('*', sort_by=['flag', '-id']) self.assertEqual([result.pk for result in results['results']], [u'1', u'3', u'2']) def test__from_python(self): self.assertEqual(self.sb._from_python('abc'), u'abc') self.assertEqual(self.sb._from_python(1), u'1') self.assertEqual(self.sb._from_python(2653), u'2653') self.assertEqual(self.sb._from_python(25.5), u'25.5') self.assertEqual(self.sb._from_python([1, 2, 3]), u'[1, 2, 3]') self.assertEqual(self.sb._from_python((1, 2, 3)), u'(1, 2, 3)') self.assertEqual(self.sb._from_python({'a': 1, 'c': 3, 'b': 2}), u"{'a': 1, 'c': 3, 'b': 2}") self.assertEqual(self.sb._from_python(datetime.datetime(2009, 5, 9, 16, 14)), u'2009-05-09T16:14:00') self.assertEqual(self.sb._from_python(datetime.datetime(2009, 5, 9, 0, 0)), u'2009-05-09T00:00:00') self.assertEqual(self.sb._from_python(datetime.datetime(1899, 5, 18, 0, 0)), u'1899-05-18T00:00:00') self.assertEqual(self.sb._from_python(datetime.datetime(2009, 5, 18, 1, 16, 30, 250)), u'2009-05-18T01:16:30.000250')