Milyonlarca kayıtta kısmi ad eşleşmesi


10

İsim eşleme için web tabanlı bir uygulama geliştirdik. İsimleri parçalara bölerek çalışır ve her parçanın Soundex değeri bir veritabanında saklanır. Levenshtein mesafe metrik verilen bir isim karşı yüzde sesin eşleştirme ve yazım uygulamak için kullanılır.

Çalışma zamanında, tüm kayıtları belleğe yükler ve tüm Soundex değerlerine Levenshtein mesafesini ve tüm adların tüm bölümlerinin yazımını uygularız.

Bu ilk başta iyi çalışıyordu çünkü maksimum 20 bin isim vardı, ama şimdi müşterilerimizden birinin 30 milyon ismi var. Bu büyük listeyi her istek için belleğe yüklemek ve bu tür eşleştirmeyi uygulamak, çok fazla bellek ve yürütme süresi kullanan acıklı bir yaklaşımdır.

Ses ve Yazım yüzdesinin eşleştirilmesiyle yakın gelecekte 30 milyon veya daha fazla kayıt içeren veritabanında arama önerileri arıyoruz.

Temel İşlevler

Son kullanıcı, eşleştirilecek adı ve minimum yüzdeyi girer. Veritabanında, adın herhangi bir bölümünün, verilen adın herhangi bir bölümüyle belirli bir yüzdeyle eşleştiği tüm bu adları göstermemiz gerekir. Tam adın eşleştirilmesi gerekmez, yüzde ile eşleşirse herhangi bir bölüm başarılı olur. Örneğin.

Given Name: Helen Hunt
Name in DB: Holly Hunter 

Her iki adın her iki kısmı da tam olarak eşleşmiyor, ancak bir dereceye kadar,% 80 olduğunu varsayalım, bu yüzden kullanıcı% 80 girerse, DB'deki adın eşleşen ad olarak gösterilmesi gerekir.


1
SQL Server kullanıyor musunuz? Asp.net etiketlendiğini görüyorum. Ağ trafiğini engelleyecek ve SQL sunucusunun belleği yönetmesine izin verecek bir CLR montajı olasılığını düşünmek.
RubberChickenLeader

@WindRaven SQL Server ve Oracle'ı kullanıyoruz
bjan

1
Bu, Google'ın çözdüğü aynı web tarama sorunu değil mi?
candied_orange

@bjan isimler nerede saklanıyor? SQL Server'da depolanıyorlar mı?
RubberChickenLeader

Ne arıyorsun? Belirli bir sorguyla en iyi eşleşen 100 ad mı?
Doc Brown

Yanıtlar:


6

İhtiyacınız olanın tüm ayrıntılarını bilmeden, muhtemelen aşağıdakilerden birini yapmak istersiniz:

Sfenks kurulum ve konfigürasyonunun neleri içerdiğini tam olarak bilmiyorum; ancak, bir veritabanına işaret edebilir, hangi alanların dizine ekleneceğini, sonuçların nasıl ağırlıklandırılacağını ve size eşleşen kayıtların sıralı bir listesini verecek bir izlenim altındayım.

Kullanıcı açısından veya görev açısından kritik öneme sahip şeyler için mevcut bir arama aracını kullanın.

Sadece akademik hissediyorsanız ... Ngramlarla oynayın:

Bir ngram arama tablosu, ilk olası eşleşmeler kümeniz olarak kullanılabilir ve sonuçları budamak ve sıralamak için Levenshtein mesafelerini kullanabilirsiniz.

Aramak istediğinizi varsayarsak people, aşağıdakine benzer bir şey yapabilirsiniz:

_ people _________
personId: int
name: varchar
soundex_name: varchar

_ people_ngrams __
personId: int
ngramId: int

_ ngrams _________
ngramId: int
ngram: char(3)
count: int

Ngramlarınızı periyodik olarak yeniden oluşturabilir veya anında oluşturabilirsiniz. Her iki durumda da, basit, naif bir arama algoritması şöyle görünebilir:

search_ngrams = ngrammify(soundex(search_string));

notable_ngrams = select top 10 *
  from ngrams
  where ngram in (search_ngrams)
  order by count asc;

possible_matches = select top 1000 distinct people.*
  from people_ngrams, people
  where ngramId in (notable_ngrams);

best_matches = top 100 possible_matches
  ordered by Levenshtein_distance(match, soundex(search_string));

Buna oldukça benzer bir şey kullanarak (ancak biraz daha fazla "popülerlik" ayarlaması, kara listeler, beyaz listeler vb.), Bu tür bir algoritmanın veri kümeleri arasında kayıtları toplu olarak birleştirdiğini ve özel bulanık aramayı kolaylaştırdığını gördüm yardımcı programlar ve devam eden kayıtların çoğaltılması çabaları.

Şimdi, benim durumumda, milyonlarca kayıtla eşleşmiyordum, her biri yüzbinlerce kayıt sırasına göre iki veri kümesi arasında mümkün olan en iyi birleştirmeyi seçmeye çalışıyordum. Birkaç dakika içinde oldukça hızlı bir şekilde çalışmasını istedik. (Çabuk, 100.000 * 100.000 nedir?) Ve başarılı olduk.

Yani, doğru ayar ile, bu tür şeyler çabuk ve etkili olabilir. Sonuçta, mütevazi, tarihli, çift çekirdekli bir makinede birkaç dakika içinde birleştirilmiş bir set üretebildik, "sorgulanabilir" birleştirmeler manuel inceleme için otomatik olarak işaretlendi. Ancak, ngram popülerliğini / alaka düzeyini tatlı noktayı ve doğru dize mesafe eşiklerini, kara listeleri ve beyaz listeleri bulmak vb. Çok zaman aldı.

DEDİ , gerçekten bu şeyler üzerinde çalışan bir delik içine emilir. Gerçek dünyadaki üretim düzeyindeki her şey için, genellikle bu tür aramalar için zaten yapılmış ve optimize edilmiş iyi yapılandırılmış bir araç kullanmalısınız .

Gibi Sfenks veya Lucene .


Sphinx 2.2.11-release referans kılavuzunda bulanık arama yaptım ve kelimeleri kısmen eşleştirmem gerekiyorken tam kelimeyle eşleştiğini görünüyor. Bu konuda yanılıyorsam düzelt.
bjan

@bjan Evet. Dokümanlara baktığımda, Sphinx'in bulanık aramasının tam olarak aradığınız şey olduğundan emin değilim. Soundex morfolojisi kullanabilir . Ama, yakın zamandaki düzenlemek dayalı, sen olabilir kendi Ngram + dize mesafeli arama rulo istiyorum. Yukarıda da söylediğim gibi, algoritmayı ve eşikleri düzeltmek biraz zaman alabilir; ama bu mümkün değil. Ve, bu esneklik seviyesine ihtiyacınız varsa ...
svidgen

Ah @bjan, ben de tamamen unutmuşum Lucene . İhtiyacınız olanı da yaptığından emin değilim; ancak, oldukça popülerdir ve kendiniz dönmeden önce bakmaya değer. Lucene belgeleri , Levenshtein dize mesafesini kullanarak bulanık arama ve sıralamalardan bahsediyor.
svidgen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.