我在Whoosh索引中有一组文档,我想提供一个搜索词建议功能。因此,如果您输入“pop”,可能会出现一些建议:
我已经将条款作为建议进入我的索引中的NGRAMWORDS字段,但是当我对该字段进行查询时,我得到自动完成的结果而不是扩展的建议 - 所以我得到了标记为“流行文化”,但无法向用户显示该术语。 (为了进行比较,我在ElasticSearch中使用该字段上的完成映射执行此操作,然后使用_suggest端点获取建议。)
我只能在文档或网络上的其他地方找到自动填充或拼写更正的示例。有什么办法可以通过Whoosh从我的索引中获取搜索词建议吗?
修改
expand_prefix
是朝着正确方向急需的指针。我最终使用KEYWORD(commas=True, lowercase=True)
作为我的建议字段,并且这样的代码以最常见的第一顺序获得建议(expand_prefix
和iter_prefix
将按字母顺序生成它们) :
def get_suggestions(term):
with ix.reader() as r:
suggestions = [(s[0], s[1].doc_frequency()) for s in r.iter_prefix('suggest', term)]
return sorted(suggestions, key=itemgetter(1), reverse=True)
答案 0 :(得分:3)
这不是您正在寻找的,但可能可以帮助您:
reader = index.reader()
for x in r.expand_prefix('title', 'pop'):
print x
输出示例:
pop
popcorn
popular
<强>更新强>
另一种解决方法是使用仅作为TEXT的关键字构建另一个索引。并使用搜索语言。我能做到的:
In [12]: list(ix.searcher().search(qp.parse('pop*')))
Out[12]:
[<Hit {'keywords': u'popcorn'}>,
<Hit {'keywords': u'popular'}>,
<Hit {'keywords': u'pope'}>,
<Hit {'keywords': u'Popular Film'}>,
<Hit {'keywords': u'pop culture'}>]
答案 1 :(得分:3)
我想在这里添加答案,实际上有一个内置函数在whoosh中返回顶部&#39;数字&#39;术语频率。它位于whoosh docs。
whoosh.reading.IndexReader.most_frequent_terms(fieldname, number=5, prefix='')
此外,在文档的同一页面上,whoosh docs中的上一个函数正上方是一个函数,它返回最多独特的术语而不是最常见的术语。它使用tf-idf分数,这有效地消除了常见但无关紧要的词语,如“&#39;”。根据您的需求,这可能或多或少有用。它被恰当地命名为:
whoosh.reading.IndexReader.most_distinctive_terms(fieldname, number=5, prefix='')
这些中的每一个都将以这种方式使用:
with ix.reader() as r:
print r.most_frequent_terms('suggestions', number=5, prefix='pop')
print r.most_distinctive_terms('suggestions', number=5, prefix='pop')
同样,我在多字建议方面遇到了问题。我的解决方案是以下列方式创建模式:
fields.Schema(suggestions = fields.TEXT(),
suggestion_phrases = fields.KEYWORD(commas=True, lowercase=True)
在suggestion_phrases
字段中,commas=True
允许关键字与空格一起存储,因此有多个单词,lowercase=True
忽略大小写(如果需要区分,则可以删除资本化和非资本化条款)。然后,为了获得单字和多字建议,您可以在两个字段上运行most_frequent_terms()
或most_distinctive_terms()
。然后结合结果。