Corrispondenza parziale del nome in milioni di record


10

Abbiamo sviluppato un'applicazione basata sul Web per la corrispondenza dei nomi. Funziona suddividendo i nomi in parti e il valore Soundex di ciascuna parte viene archiviato in un database. La metrica della distanza Levenshtein viene utilizzata per applicare la corrispondenza percentuale del suono e l'ortografia rispetto a un determinato nome.

In fase di esecuzione, cariciamo tutti i record in memoria e applichiamo la distanza di Levenshtein a tutti i valori di Soundex e l'ortografia di tutte le parti di tutti i nomi.

All'inizio funzionava bene perché c'erano al massimo 20 mila nomi, ma ora uno dei nostri clienti ha 30 milioni di nomi. Caricare questo enorme elenco in memoria per ogni richiesta e applicare questo tipo di corrispondenza è un approccio patetico, usando molta memoria e tempi di esecuzione.

Siamo alla ricerca di suggerimenti per la ricerca nel database di 30 milioni di record o più nel prossimo futuro con una corrispondenza percentuale di suoni e ortografia.

Funzionalità di base

L'utente finale inserisce il nome da abbinare e la percentuale minima. Dovremmo mostrare tutti quei nomi nel database per i quali ogni parte del nome corrisponde a qualsiasi parte del nome dato fino alla percentuale indicata. Il nome completo non deve essere abbinato, qualsiasi parte se corrisponde alla percentuale è un successo. Per esempio.

Given Name: Helen Hunt
Name in DB: Holly Hunter 

Entrambe le parti di entrambi i nomi non corrispondono esattamente ma fino a un certo punto, ipotizziamo l'80%, quindi se l'utente immette l'80%, il nome nel DB deve essere mostrato come nome corrispondente.


1
Stai usando SQL Server? Vedo che l'hai taggato asp.net. Pensando alla possibilità di un assembly CLR che impedirebbe il traffico di rete e consentirebbe a SQL Server di gestire la memoria.
RubberChickenLeader

@WindRaven stiamo usando sia SQL Server che Oracle
bjan,

1
Non è lo stesso problema di scansione del Web risolto da Google?
candied_orange

@bjan dove sono memorizzati i nomi? sono archiviati in SQL Server?
RubberChickenLeader

Che cosa stai cercando? I primi 100 nomi che corrispondono meglio a una determinata query?
Doc Brown,

Risposte:


6

Senza conoscere i dettagli completi di ciò di cui hai bisogno, probabilmente vorrai fare una delle seguenti operazioni:

Non so bene cosa comporta l'installazione e la configurazione della sfinge; ma ho l'impressione che tu possa puntarlo a un database, dirgli quali campi indicizzare, come ponderare i risultati e ti darà un elenco ordinato di record corrispondenti.

Per argomenti rivolti all'utente o mission-critical, utilizza uno strumento di ricerca esistente.

Se ti senti solo accademico ... Gioca con gli ngram:

Una tabella di ricerca di ngram può servire da insieme iniziale di potenziali corrispondenze e puoi usare le distanze di Levenshtein per potare e ordinare i risultati.

Supponendo che tu voglia cercare people, potresti fare qualcosa del tipo:

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

_ people_ngrams __
personId: int
ngramId: int

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

Puoi periodicamente ricostruire i tuoi ngram o costruirli al volo. Ad ogni modo, un algoritmo di ricerca semplice e ingenuo può apparire così:

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

Usando qualcosa di abbastanza simile a questo (ma con un po 'più di sintonizzazione "popolarità" ngram, blacklist, whitelist, ecc.), Ho visto questo tipo di algoritmo unire confusamente i record tra set di dati in blocco, oltre a facilitare la ricerca fuzzy personalizzata programmi di utilità per la de-duplicazione delle registrazioni in corso.

Ora, nel mio caso, non stavo abbinando milioni di record, stavo cercando di selezionare le migliori fusioni possibili tra due set di dati nell'ordine di centinaia di migliaia di record ciascuno. E volevamo che funzionasse abbastanza rapidamente - in pochi minuti. (Veloce, cosa sono 100.000 * 100.000?) E abbiamo avuto successo.

Quindi, con la giusta sintonia, questo genere di cose può essere scattante ed efficace. Alla fine siamo stati in grado di produrre in pochi minuti un set unito su una macchina umile, datata, dual core, con fusioni "discutibili" contrassegnate automaticamente per la revisione manuale. Ma, ci è voluto molto tempo per trovare il punto debole di popolarità / rilevanza ngram e le giuste soglie di distanza stringa, le liste nere e le whitelist ... ecc.

Detto questo , puoi davvero essere risucchiato in un buco lavorando su questa roba. Per qualsiasi materiale a livello di produzione nel mondo reale, dovresti generalmente utilizzare uno strumento ben consolidato che è già stato creato e ottimizzato per questo tipo di ricerca.

Come Sfinge o Lucene .


Ho appena cercato fuzzy nel manuale di riferimento della versione 2.2.11 di Sphinx e sembra che corrisponda alla parola esatta mentre devo abbinare parzialmente le parole. Correggimi se sbaglio su questo.
bjan,

@bjan Sì. Esaminando ulteriormente i documenti, non sono sicuro che la ricerca confusa di Sphinx sia esattamente ciò che stai cercando. Può usare una morfologia soundex . Ma, in base alla recente modifica, si potrebbe desiderare di rotolare il proprio Ngram + stringa di ricerca distanza. E come ho detto sopra, può essere necessario un po 'di tempo per modificare l'algoritmo e le soglie per ottenere il risultato corretto; ma non è fattibile. E, se hai bisogno di quel livello di flessibilità ...
svidgen,

@bjan Oh, mi sono anche completamente dimenticato di Lucene . Non sono sicuro che faccia anche quello di cui hai bisogno; ma, è dannatamente popolare, e vale la pena guardarlo prima di fare il tuo. I documenti di Lucene menzionano ricerche e classifiche sfocate usando la distanza della stringa di Levenshtein.
svidgen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.