2011-07-15 33 views
10

MongoDB'de büyük bir banka veri tabanı oluşturdum. Bu bilgiyi kolaylıkla alabiliyorum ve bununla birlikte indeksler yaratabiliyorum. Mesela 'Kartal Bankası'nın & Trust Co of Missouri' ve 'Eagle Bank ve Trust Company of Missouri' banka isimlerini uydurmak istiyorum. Aşağıdaki kod basit bulanık böyle çalışır, ancak yukarıda bir maç ulaşamayacağını:Fuzzy String Python'da Whoosh ile arama

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 

bana verir:

<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> 

ben whoosh ile istediğinizi elde etmek mümkün mü? Başka hangi python tabanlı çözümlere sahip değilim?

cevap

7

Sen maç olabilir Co whoosh içinde Bulanık Search kullanarak ancak Co ve Company arasındaki fark büyük olduğu için değil gerektiğini Company ile. CoCompanyBeBeast ve nyCompany ile benzerdir, ne kadar kötü ve arama sonuçları ne kadar büyük olacağını hayal edebilirsiniz. Eğer Company için Compan veya compani veya Companee eşleştirmek istiyorsanız,

Ancak, 2 veya daha fazla varsayılan eşit maxdist ile FuzzyTerm bir Kişiselleştirilmiş Class kullanarak bunu yapabilirsiniz:

maxdist - maksimum Verilen metinden uzaklığı düzenlemek. Sonra

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) 

Sen 5 için maxdist ayarlayarak Company ile Co eşleşebilir ama bu kötü arama sonuçları verir söylediği gibi. maxdist'u 1'dan 3'a saklamayı öneririm.

Bir sözcük dilbilgisi varyasyonlarını eşleştirmek istiyorsanız, whoosh.query.Variations numaralı telefonu kullanmalısınız.

Not: büyük Whoosh sürümleri maxdist yerine minsimilarity sahiptir.

Bir ifade karşı kelime kümesi arama zabıta Aşağıdaki bu fonksiyonu kullanabilirsiniz
3

ve bir şekilde bunu yapmak için daha iyi bir yolu olmalı, ama burada benim atış.

# -*- 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

:

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