django-haystack elasticsearch多个索引错误的结果

时间:2015-02-26 13:39:08

标签: python django elasticsearch django-haystack

我在我的网站中使用django-haystack + elasticsearch设置了搜索索引。有不同的索引,一般来说它们正常工作,但是当我搜索Person时,ProjectIndex除外。让我解释一下:

这些是模特:

class Person(models.Model):
    first_name = models.CharField()
    last_name = models.CharField()

class Project(models.Model):
    project_name = models.CharField()
    employees = models.ManyToManyField(Person)

这些是索引:

class ProjectIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.EdgeNgramField(document=True, use_template=True)
    project_name = indexes.CharField(model_attr='project_name', boost=1.4)
    employees = indexes.CharField(boost=1.5)

    def get_model(self):
        return Project

    def prepare_employees(self, obj):
        return ' '.join([employee.__unicode__() for employee in obj.employees.all()])

    def prepare(self, obj):
        data = super(ProjectIndex, self).prepare(obj)
        data['boost'] = 1.3
        return data

class PersonIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.EdgeNgramField(document=True, use_template=True)
    first_name = indexes.CharField(model_attr='first_name', boost=1.1)
    last_name = indexes.CharField(model_attr='last_name', boost=1.2)

    def get_model(self):
        return Person

当我运行rebuild_index时,所有项目似乎都被正确编入索引。当我搜索一个人时,对弹性搜索服务器的简单http查询返回有用的项目结果(非常有意义)。

>>> from urllib import urlopen
>>> response = urlopen('http://127.0.0.1:9200/_search?q=' + q)
>>> json_data = response.read()
>>> from json import loads
>>> d = loads(json_data)
>>> f = filter(lambda d: d['_source']['django_ct'] == "project.project", d['hits']['hits'])
>>> len(f)
8

另一方面,SearchQuerySet只返回3个项目,其中不涉及此人,此人名称也与项目名称相似。

>>> sqs = SearchQuerySet().filter(content__auto=q)
>>> sqs.count()
8
>>> sqs.models(Project)
[<SearchResult: project.project (pk=u'409')>, <SearchResult: project.project (pk=u'521')>, <SearchResult: project.project (pk=u'82')>]

我在这里做错了吗?感谢您的反馈: - )

1 个答案:

答案 0 :(得分:0)

我通过修改filter()查询设法获得了更好的质量结果。我在django-haystack文档中了解了filter_or()方法,它可以根据需要连接多次。通过这种方式,可以根据需要轻松匹配多个字段和/或索引。例如:

sqs = SearchQuerySet().filter_or(content__contains=q).filter_or(employees__name__contains=q).filter_or(projects_name__contains=q)
# etc.

正如刚才所说,这提高了搜索结果的质量。