使用 Whoosh 生成搜索词建议



我在 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)

术语频率函数

我想在这里补充一点,实际上 whoosh 中有一个内置函数,它按术语频率返回顶部"数字"项。它在嗖嗖声文档中。

whoosh.reading.IndexReader.most_frequent_terms(fieldname, number=5, prefix='')

TF-IDF 与频率

此外,在文档的同一页面上,在 whoosh 文档中的上一个函数的正上方是一个返回最独特的术语而不是最频繁的术语的函数。它使用 tf-idf 分数,该分数可有效消除常见但无关紧要的单词,如"the"。这可能或多或少有用,具体取决于您要查找的内容。它被恰当地命名为:

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()。然后合并结果。

这不是您要找的,但可能会帮助您:

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'}>]

最新更新