[英]Fuzzy String Searching with Whoosh in Python
我在 MongoDB 中建立了一個大型銀行數據庫。 我可以輕松地獲取這些信息並用它創建索引。 例如,我希望能夠匹配銀行名稱“Eagle Bank & Trust Co of Missouri”和“Eagle Bank and Trust Company of Missouri”。 以下代碼適用於簡單的模糊等,但無法實現上述匹配:
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>
Whoosh可以實現我想要的嗎? 如果沒有,我還有什么其他基於 python 的解決方案?
您可以使用 Whoosh 中的模糊搜索將Co
與Company
匹配,但您不應該這樣做,因為Co
和Company
之間的差異很大。 Co
與Company
相似, Be
與Beast
相似, ny
與Company
相似,您可以想象搜索結果會有多糟糕和有多大。
但是,如果您想將Compan
或compani
或Companee
與Company
匹配,您可以使用 FuzzyTerm 的個性化 Class 來FuzzyTerm
,默認maxdist
等於或大於 2:
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)
您可以通過將maxdist
設置為5
來將Co
與Company
匹配,但正如我所說,這會給出錯誤的搜索結果。 我建議保持maxdist
從1
到3
。
如果您正在尋找匹配單詞的語言變體,您最好使用whoosh.query.Variations
。
注意:較舊的 Whoosh 版本具有minsimilarity
而不是maxdist
。
為了將來參考,必須有更好的方法來做到這一點,但這是我的鏡頭。
# -*- 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()
也許其中一些東西可能會有所幫助(由 seatgeek 家伙開源的字符串匹配):
對於最近遇到這個問題的任何人,看起來他們已經在本地添加了模糊支持,盡管需要一些工作才能滿足此處概述的特定用例: https://whoosh.readthedocs.io/en/最新/解析.html
您可以使用下面的 function 對一組單詞進行模糊搜索:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.