用Whoosh生成搜索词建议?

时间:2015-01-23 10:57:38

标签: python whoosh search-suggestion

我在Whoosh索引中有一组文档,我想提供一个搜索词建议功能。因此,如果您输入“pop”,可能会出现一些建议:

  • 爆米花
  • 流行
  • 教皇
  • 杨树电影
  • 流行文化

我已经将条款作为建议进入我的索引中的NGRAMWORDS字段,但是当我对该字段进行查询时,我得到自动完成的结果而不是扩展的建议 - 所以我得到了标记为“流行文化”,但无法向用户显示该术语。 (为了进行比较,我在ElasticSearch中使用该字段上的完成映射执行此操作,然后使用_suggest端点获取建议。)

我只能在文档或网络上的其他地方找到自动填充或拼写更正的示例。有什么办法可以通过Whoosh从我的索引中获取搜索词建议吗?

修改 expand_prefix是朝着正确方向急需的指针。我最终使用KEYWORD(commas=True, lowercase=True)作为我的建议字段,并且这样的代码以最常见的第一顺序获得建议(expand_prefixiter_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)

2 个答案:

答案 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='')

tf-idf与频率

此外,在文档的同一页面上,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()。然后结合结果。