使用Haystack/Elasticsearch进行部分单词搜索

4
我们目前正在使用基于Elasticsearch的Haystack。我们在部分词搜索方面遇到了麻烦。
我们当前已经有了一个含有EdgeNgramField的索引。我试图在该字段上进行搜索,但除了精确匹配的结果外,没有找到其他结果。我试图用它来查找产品,例如:我输入“sun”,但我无法获得“sunglasses”的结果。
我开始直接使用curl命令在elasticsearch上进行操作,以查明出现了什么情况。我甚至使用curl直接创建了自己的索引,并使用ngram分析器,通过部分词搜索获得了正确的结果。
另一个有趣的事情是:如果我在我的测试索引上直接在elasticsearch上运行_mapping命令,我会得到如下结果:“testfield”:{"type":"string","analyzer":"test_analyzer"},然而,如果我在由haystack创建的索引上运行映射命令,它只有"type":"string",并没有任何关于应该使用的edgengram_analyzer的信息。
你有什么想法吗?
1个回答

5

我认为在elasticsearch_backend.py中的haystack存在一个bug,它没有正确地使用pyelasticsearch。第868行看起来像这样:

self.conn.put_mapping('modelresult', current_mapping, index=self.index_name)

如果您将其替换为:

self.conn.put_mapping(doc_type='modelresult', mapping=current_mapping, index=self.index_name)

如果您按照pyelasticsearch所期望的方式进行配置,那么您将会看到edgengram_analyzer已经添加到了EdgeNgramField字段中。至少对于我来说是有效的。

我现在遇到的问题是自动完成只有在单词与产品名称开头匹配时才返回结果。否则它将无法工作。 因此,如果我搜索“sun”,它将返回“太阳镜”。但是如果我搜索“glass”,我就没有结果了。尽管它也应该返回“太阳镜”?! - Salma Hamed
没问题。你需要的是 ngram 而不是 edge ngram。Edge NGram 用于匹配单词的开头或结尾,而ngram则指单词中连续的一组字母(至少在信息提取方面是这样)。顺便说一下,如果这不能回答你的第二个问题,请创建一个新的问题,以便我们进行讨论并提供答案。 - racedo
这个问题在 Elasticsearch 的官方后端版本中得到了修复吗?还是说我仍然需要进行更改? - Nathan Keller
为了回答我的子问题,没有,参见https://github.com/toastdriven/django-haystack/blob/master/haystack/backends/elasticsearch_backend.py#L132 - Nathan Keller
我仍然只能在长度为3的字符串或完整单词上使用NGram来获得结果,而不能在任意长度的字符串上使用。 - Nathan Keller
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接