Merged field_weights branch

This commit is contained in:
David Sauve 2010-07-21 19:13:26 -04:00
parent a07a980662
commit 29ae7f7672
2 changed files with 78 additions and 14 deletions

View file

@ -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'
])

View file

@ -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),