diff --git a/tests/xapian_tests/tests/xapian_backend.py b/tests/xapian_tests/tests/xapian_backend.py index 4d247d3..5d6a4fb 100644 --- a/tests/xapian_tests/tests/xapian_backend.py +++ b/tests/xapian_tests/tests/xapian_backend.py @@ -18,7 +18,7 @@ from haystack.exceptions import HaystackError from haystack.query import SearchQuerySet, SQ from haystack.sites import SearchSite -from core.models import MockTag, MockModel, AnotherMockModel +from core.models import MockTag, MockModel, AnotherMockModel, AFourthMockModel class XapianMockModel(models.Model): @@ -95,6 +95,16 @@ class XapianMockSearchIndex(indexes.SearchIndex): return '' +class XapianBoostMockSearchIndex(indexes.SearchIndex): + text = indexes.CharField( + document=True, use_template=True, + template_name='search/indexes/core/mockmodel_template.txt' + ) + author = indexes.CharField(model_attr='author', weight=2.0) + editor = indexes.CharField(model_attr='editor') + pub_date = indexes.DateField(model_attr='pub_date') + + class XapianSearchBackendTestCase(TestCase): def setUp(self): super(XapianSearchBackendTestCase, self).setUp() @@ -473,3 +483,53 @@ class LiveXapianSearchQueryTestCase(TestCase): # Restore. settings.DEBUG = old_debug + + +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' + ]) diff --git a/xapian_backend.py b/xapian_backend.py index ad6d1a3..2fd1a89 100755 --- a/xapian_backend.py +++ b/xapian_backend.py @@ -205,41 +205,45 @@ class SearchBackend(BaseSearchBackend): document_id = DOCUMENT_ID_TERM_PREFIX + get_identifier(obj) data = index.full_prepare(obj) - + weights = index.get_field_weights() for field in self.schema: if field['field_name'] in data.keys(): prefix = DOCUMENT_CUSTOM_TERM_PREFIX + field['field_name'].upper() value = data[field['field_name']] + try: + weight = int(weights[field['field_name']]) + except KeyError: + weight = 1 if field['type'] == 'text': if field['multi_valued'] == 'false': term = _marshal_term(value) - term_generator.index_text(term) - term_generator.index_text(term, 1, prefix) + term_generator.index_text(term, weight) + term_generator.index_text(term, weight, prefix) if len(term.split()) == 1: - document.add_term(term) - document.add_term(prefix + term) + document.add_term(term, weight) + document.add_term(prefix + term, weight) document.add_value(field['column'], _marshal_value(value)) else: for term in value: term = _marshal_term(term) - term_generator.index_text(term) - term_generator.index_text(term, 1, prefix) + term_generator.index_text(term, weight) + term_generator.index_text(term, weight, prefix) if len(term.split()) == 1: - document.add_term(term) - document.add_term(prefix + term) + document.add_term(term, weight) + document.add_term(prefix + term, weight) else: if field['multi_valued'] == 'false': term = _marshal_term(value) if len(term.split()) == 1: - document.add_term(term) - document.add_term(prefix + term) + document.add_term(term, weight) + document.add_term(prefix + term, weight) document.add_value(field['column'], _marshal_value(value)) else: for term in value: term = _marshal_term(term) if len(term.split()) == 1: - document.add_term(term) - document.add_term(prefix + term) + document.add_term(term, weight) + document.add_term(prefix + term, weight) document.set_data(pickle.dumps( (obj._meta.app_label, obj._meta.module_name, obj.pk, data),