Django haystack,搜索中某些字段的优先级

时间:2012-05-10 16:59:09

标签: django search django-haystack whoosh

我有一个这样的模型:

class MyModel(models.Model):
    desc1 = models.TextField(blank=True, default="")
    desc2 = models.TextField(blank=True, default="")

我想在此模型的字段上搜索字符串。假设MyModel的这些实例:

1: desc1="ABc?", desc2="asdasd you"
2: desc1="Hello, How are you?", desc2="Thank you!"
3: desc1="ABc?", desc2="ajdf"

当我搜索"你"时,它应该显示我,第一和第二个实例。 最后,我需要显示结果,这些结果是"你"在desc1高于其他人。例如,在此示例中,第二个应高于第一个。

我使用了haystack进行搜索并为此创建了一个模板。但我无法解决优先问题。

2 个答案:

答案 0 :(得分:2)

当你说'优先'时,你的意思是'排序',在搜索的语言中。

Django Haystack可以按字段匹配排序,但它可以按“得分”排序,它使用算法来确定排序顺序。您可以通过“提升”来影响分数的加权 - 请参阅 http://django-haystack.readthedocs.org/en/latest/boost.html

此外,您应该考虑在search_indexes.py中添加仅用于加权的额外字段。您不需要在Django模型字段和索引之间建立一对一的映射。像

这样的东西
class MyModelIndex(QueuedSearchIndex):
    desc1 = indexes.CharField()
    desc2 = indexes.CharField()
    otherWeightedField = indexes.CharField()

    def prepare_otherWeightedField(self,obj)
        # fill the extra field with extra stuff to help you sort, based on processing values from other fields

答案 1 :(得分:1)

我使用这种方法。

from types import ListType
from haystack import indexes


class DocumentField(indexes.SearchField):
    """An index field that combines and weights other fields because Haystack
    does not provide for weighted searching. This field makes use of other
    existing field classes for DRY."""

    def __init__(self, *args, **kwargs):
        self.fields = kwargs.pop("fields", None)
        super(DocumentField, self).__init__(*args, **kwargs)
        self.document = True
        self.use_template = False

    def prepare(self, obj):
        values = []

        for field_instance in self.fields.values():
            v = field_instance.prepare(obj)
            if not v:
                continue
            if not isinstance(v, ListType):
                v = [v]
            # Apply boost
            v = v * int(field_instance.boost * 10)
            values.extend(v)

        return "\n".join(values)


class MyModelIndex(indexes.SearchIndex, indexes.Indexable):
    text = DocumentField(fields=dict(
        desc1 = indexes.CharField(model_attr="desc1", boost=1.0),
        desc2 = indexes.CharField(model_attr="desc2", boost=0.7)
    ))

    def get_model(self):
        return MyModel