0

我正在尝试在我的服务器上进行自动完成以进行搜索。这是我的索引器类之一的示例:

class ArtistIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    artist_name = indexes.CharField(model_attr='clean_artist_name', null=True)
    submitted_date = indexes.DateTimeField(model_attr='submitted_date')
    total_count = indexes.IntegerField(model_attr='total_count')

    # This is used for autocomplete
    content_auto = indexes.NgramField(use_template=True)

    def get_model(self):
        return Artist

    def index_queryset(self, using=None):
        """ Used when the entire index of a model is updated. """
        return self.get_model().objects.filter(date_submitted__lte=datetime.now())

    def get_updated_field(self):
        return "last_data_change"

和字段使用模板填充,在 Artsts 的情况下,模板只是艺术家姓名textcontent_auto根据文档,这样的东西应该适用于自动完成:

objResultSet = SearchQuerySet().models(Artist).autocomplete(content_auto=search_term)

但是,尝试使用字符串“bill w”返回 Bill Stephney 作为顶部结果,然后返回 Bill Withers 作为第二个结果。这是因为 Bill Stephney 在数据库中有更多记录,但 Stephney 不应该匹配这个查询:一旦检测到“w”,它应该只匹配 Bill Withers(和其他 Bill Ws)。我也尝试过通配符:

objResultSet = SearchQuerySet().models(Artist).filter(content_auto=search_term + '*')

objResultSet = SearchQuerySet().models(Artist).filter(text=AutoQuery(search_term + '*'))

但是通配符似乎会导致很多问题,开发服务器挂起并最终由于Write Failed: Broken Pipe一个神秘的堆栈跟踪错误而停止,所有这些都在 Python 框架内。有没有人设法让它正常工作?NgramField 是正确使用的类型吗?我试过使用 EdgeNgramField 但这给了我类似的结果。

4

1 回答 1

0

我相信 Haystack 文档建议将 EdgeNgramField用于“标准文本”,我认为它是英文的。他们推荐NgramField用于亚洲语言,或者如果您想跨单词边界进行匹配。即,我认为您希望您的content_auto使用EdgeNgramField

 content_auto = indexes.EdgeNgramField(use_template=True)

此外,由于 n-gram 并不完全是通配符搜索(例如,我们在 shell 脚本 glob 匹配中使用 * [星号]),因此您不应在过滤器中使用 *。

我发现对搜索结果产生影响的一件事是您可以在后端引擎中调整的参数——n-gram 标记器和 n-gram 过滤器的设置。根据您使用的搜索引擎后端,更改min_gram值将影响您在匹配中获得的结果。

我只使用了elasticsearch后端,所以我不知道其他后端是否像 solr/elasticsearch 那样对这些 n-gram 设置敏感。基本上,我基于 haystack 附带的默认后端创建了一个自定义后端,并调整了min_gram值以测试匹配。您设置的值越高,匹配就越“准确”,因为它必须匹配更长的标记。

请参阅有关为弹性搜索使用具有自定义 n-gram 设置的后端的问题:

于 2014-07-25T08:34:12.413 回答