2009-12-17 12 views
6

Ecco il mio problema. Per esempio ho una tabella Prodotti che contiene un campo, Nome:Utilizzare SOUNDEX() parola per parola su SQL Server

Products 
ID | Name | .. 
1 | "USB Key 10Go" 
2 | "Intel computer" 
3 | "12 inches laptop computer" 
... 

Attualmente sto implementando un semplice motore di ricerca (SQL Server e ASP .NET, C#) per un iPhone web-app e vorrei usare la funzione di SQL Server SOUNDEX().

Il fatto è che non posso utilizzare direttamente SOUNDEX sul Nome campo. (Questo sarebbe irrilevante dal momento che ci sono diverse parole nel nome.) Vorrei applicare la funzione SOUNDEX a ogni parola dal campo Nome, e poi vedere se qualcuno di questi corrisponde alla parola chiave ricercata.

Se qualcuno ha qualche idea su come farlo, sarebbe fantastico.

+0

Quanti record sono presenti nella tabella prodotti. Una soluzione di programmazione (ad esempio, l'analisi del campo del nome in un campo separato e quindi l'applicazione di soundex a ciascuno) verrà eseguita lentamente in una query. Potresti fare meglio a cambiare la struttura del tuo database, se questa è una possibilità. – Sparky

+0

sì, se il set di dati è grande per qualsiasi confronto, ci vorrà un'eternità per l'esecuzione. – DForck42

+0

Sì, il database è di grandi dimensioni, questo è quello che sto facendo attualmente (sul codice C# .NET, usando regexp per contare il numero di parole e aggiungere rilevanza per me stesso ai risultati della ricerca) ma è molto lento. In questo momento sto esaminando FREETEXT ma ho riscontrato qualche problema (vedi http://stackoverflow.com/questions/1923806/how-to-turn-on-thelfulltext-mode-on-ms-sql-2005) . – Charles

risposta

4

Hai esaminato la funzionalità di ricerca full-text in SQL Server? So che questo non è esattamente quello che hai chiesto. È solo che la funzione SOUNDEX() viene utilizzata per trovare nomi SOUNDING simili (EX: SMITH e SMYTHE suonano allo stesso modo). In un motore di ricerca, tuttavia, il modo in cui una parola suona è meno importante delle parole di ricerca stesse. La ricerca full-text ti consente anche di utilizzare sinonimi (che ti consentono di specificare determinate parole che significano la stessa cosa nel contesto dell'applicazione) e di tenerle automaticamente in considerazione durante la ricerca.

Guardate queste pagine per ulteriori informazioni sulla ricerca full-text in SQL Server:

Introduction to Full-Text Search

CONTAINS

CONTAINSTABLE

FREETEXT

FREETEXTTABLE

+0

Ho visto FREETEXT, il problema è che ho grossi problemi nell'installarlo. Quando ho cercato di attivare la modalità full-text, ma ottengo un errore: USO [AspDotNetStorefront] GO EXEC sp_fulltext_database 'abilitare' GO CREATE FULLTEXT CATALOGO searchcatalog GO -> Msg 7609, Livello 17 , Stato 100, Linea 1 La ricerca full-text non è installata oppure non è possibile caricare un componente full-text. – Charles

+0

Sembra che il servizio FULLTEXT non sia installato e/o in esecuzione. Se si esegue SQL Server Express, il servizio FULLTEXT non è incluso a meno che non si disponga della versione che include servizi avanzati. Ecco il link per il 2005 (http://www.microsoft.com/downloads/details.aspx?familyid=4C6BA9FD-319A-4887-BC75-3B02B5E48A40&displaylang=en) ed ecco il link per il 2008 (http: //www.microsoft.com/express/sql/download/). Se è stata installata questa versione, controllare se il servizio di ricerca di FullText è in esecuzione (Configuration Manager, sotto servizi). –

5

Piuttosto che usare Soundex, è meglio calcolare la distanza tra le due corde di Levenshtein. Vedi the Wikipedia article on Levenshtein distance.

Esiste un'implementazione TSQL dell'algoritmo di distanza Levenshtein here.

Condividi e divertiti.


EDIT 03-mag-2012

Dopo aver scritto la mia risposta originale ho imparato che Oracle include la distanza Levenshtein e diverse altre funzioni "stringa" somiglianza nel pacchetto UTL_MATCH, che credo sia un parte standard del database. Documentazione here. Forse non direttamente correlato al post originale (che era per SQL Server) ma forse utile come molti negozi utilizzano più database.

1

Se si deve fare tutto nel RDBMS, un UDF sarebbe il migliore se si tratta di un'opzione.

In caso contrario, è possibile utilizzare questa tecnica per almeno SOUNDEX le prime quattro parole singolarmente utilizzando PARSENAME:

Da How do I split a string so I can access item x?:

PARSENAME(REPLACE('12 inches laptop computer', ' ', '.'), 1) --return computer 
PARSENAME(REPLACE('12 inches laptop computer', ' ', '.'), 2) --return laptop 
... 

Tuttavia: utilizzando ParseName in questo modo è un hack e un serio la limitazione è che funziona solo per un massimo di 4 parti. Se ci sono 5 o più parole PARSENAME restituirà NULL, quindi devi verificarlo con un condizionale e degradare con grazia.

Ecco un esempio semplificato (ancora una volta, senza i controlli NULL)

SELECT * 
FROM Products 
WHERE SOUNDEX(search_input) = SOUNDEX(PARSENAME(REPLACE(Name, ' ', '.'), 4)) 
    OR SOUNDEX(search_input) = SOUNDEX(PARSENAME(REPLACE(Name, ' ', '.'), 3)) 
    OR SOUNDEX(search_input) = SOUNDEX(PARSENAME(REPLACE(Name, ' ', '.'), 2)) 
    OR SOUNDEX(search_input) = SOUNDEX(PARSENAME(REPLACE(Name, ' ', '.'), 1)) 
1

Il SOUNDEX può essere una misura perfetta per la vostra purpuse, ma vi prego di ricordare che non può fornire buoni risultati di qualcosa di diverso britannico o parole parlate inglese americano! Può anche essere usato su parole parlate fonetiche tedesche, ma non funzionerà bene con QUALSIASI altro.

1

Si potrebbe provare a memorizzare il metaphone di ogni parola concatenato con trattini. Il campo EG stored_metaphone potrebbe contenere qualcosa come "-AKTRF-SPLS-". Quindi creare una query come questa:

$where = '('; 
$search_sql = array(); 
$search_terms = explode(' ',$search); 
foreach ($search_terms as $term) { 
    $search_sql[] = "`stored_metaphone` LIKE '%-".metaphone($term)."-%'"; 
} 
$where .= implode(' OR ',$search_sql); 
$where .= ')'; 

NB questa è solo la parte WHERE della query.

Per quanto ne so, il metaphone funziona solo con l'inglese. Quanto sopra sql funziona piuttosto bene su un numero di siti.

Problemi correlati