用Python中的Whoosh搜索模糊字符串

时间:2011-07-15 15:55:52

标签: python information-retrieval fuzzy-search whoosh

我在MongoDB中建立了一个庞大的银行数据库。我可以轻松地获取此信息并在其中创建索引。例如,我希望能够匹配银行名称'Eagle Bank&密苏里州信托公司和密苏里州鹰公司和信托公司。以下代码适用于简单模糊这样,但无法实现上述匹配:

from whoosh.index import create_in
from whoosh.fields import *

schema = Schema(name=TEXT(stored=True))
ix = create_in("indexdir", schema)
writer = ix.writer()

test_items = [u"Eagle Bank and Trust Company of Missouri"]

writer.add_document(name=item)
writer.commit()

from whoosh.qparser import QueryParser
from whoosh.query import FuzzyTerm

with ix.searcher() as s:
    qp = QueryParser("name", schema=ix.schema, termclass=FuzzyTerm)
    q = qp.parse(u"Eagle Bank & Trust Co of Missouri")
    results = s.search(q)
    print results

给了我:

<Top 0 Results for And([FuzzyTerm('name', u'eagle', boost=1.000000, minsimilarity=0.500000, prefixlength=1), FuzzyTerm('name', u'bank', boost=1.000000, minsimilarity=0.500000, prefixlength=1), FuzzyTerm('name', u'trust', boost=1.000000, minsimilarity=0.500000, prefixlength=1), FuzzyTerm('name', u'co', boost=1.000000, minsimilarity=0.500000, prefixlength=1), FuzzyTerm('name', u'missouri', boost=1.000000, minsimilarity=0.500000, prefixlength=1)]) runtime=0.00166392326355>

有可能通过飞快移动达到我想要的效果吗?如果不是我有其他基于python的解决方案吗?

4 个答案:

答案 0 :(得分:6)

您可以Co使用模糊搜索在Whoosh中匹配,但您不应该,因为{{之间的差异1}}和Company很大。 CoCompany类似,Co类似于CompanyBeBeast,您可以想象有多么糟糕,有多大搜索结果。

但是,如果您希望将nyCompanyCompancompani匹配,则可以使用默认的Companee个性化类进行匹配Company等于2或更多:

  

maxdist - 与给定文字的最大编辑距离。

FuzzyTerm

然后:

maxdist

通过将class MyFuzzyTerm(FuzzyTerm): def __init__(self, fieldname, text, boost=1.0, maxdist=2, prefixlength=1, constantscore=True): super(MyFuzzyTerm, self).__init__(fieldname, text, boost, maxdist, prefixlength, constantscore) 设置为 qp = QueryParser("name", schema=ix.schema, termclass=MyFuzzyTerm) ,您可以将CoCompany匹配,但正如我所说,这会给出错误的搜索结果。我建议将maxdist5保留到maxdist

如果您正在寻找匹配单词语言变体,最好使用whoosh.query.Variations

注意:较早的Whoosh版本有1而不是3

答案 1 :(得分:3)

为了将来的参考,必须有更好的方法以某种方式做到这一点,但这是我的镜头。

# -*- coding: utf-8 -*-
import whoosh
from whoosh.index import create_in
from whoosh.fields import *
from whoosh.query import *
from whoosh.qparser import QueryParser

schema = Schema(name=TEXT(stored=True))
idx = create_in("C:\\idx_name\\", schema, "idx_name")

writer = idx.writer()

writer.add_document(name=u"This is craaazy shit")
writer.add_document(name=u"This is craaazy beer")
writer.add_document(name=u"Raphaël rocks")
writer.add_document(name=u"Rockies are mountains")

writer.commit()

s = idx.searcher()
print "Fields: ", list(s.lexicon("name"))
qp = QueryParser("name", schema=schema, termclass=FuzzyTerm)

for i in range(1,40):
    res = s.search(FuzzyTerm("name", "just rocks", maxdist=i, prefixlength=0))
    if len(res) > 0:
        for r in res:
            print "Potential match ( %s ): [  %s  ]" % ( i, r["name"] )
        break
    else:
        print "Pass: %s" % i

s.close()

答案 2 :(得分:1)

也许这些东西中的一些可能会有所帮助(由seatgeek家伙开源的字符串匹配):

https://github.com/seatgeek/fuzzywuzzy

答案 3 :(得分:-2)

您可以使用以下此功能模糊搜索一组词语:

def FuzzySearch(text, phrase):
    """Check if word in phrase is contained in text"""
    phrases = phrase.split(" ")

    for x in range(len(phrases)):
        if phrases[x] in text:
            print("Match! Found " + phrases[x] + " in text")
        else:
            continue