La conversione di query di ricerca immessa dall'utente al punto in cui la clausola per l'uso in ricerca full-text di SQL Server
-
21-08-2019 - |
Domanda
Qual è il modo migliore per convertire i termini di ricerca inseriti da un utente, in una query che può essere utilizzato in una clausola dove per ricerca full-text per interrogare un tavolo e tornare risultati rilevanti? Ad esempio, la seguente query immessa dall'utente:
+"e-mail" +attachment -"word document" -"e-learning"
dovrebbe tradursi in qualcosa di simile:
SELECT * FROM MyTable WHERE (CONTAINS(*, '"e-mail"')) AND (CONTAINS(*, '"attachment"')) AND (NOT CONTAINS(*, '"word document"')) AND (NOT CONTAINS(*, '"e-learning"'))
Io sto usando un classe parser in questo momento, che analizza la query inserite dagli utenti in token utilizzando un'espressione regolare, e poi costruisce la clausola in cui dai gettoni.
Tuttavia, dato che questo è probabilmente un requisito comune da un sacco di sistemi che utilizzano la ricerca full-text, io sono curioso di sapere come altri sviluppatori hanno affrontato questo problema, e se c'è un modo migliore di fare le cose.
Soluzione
Questo potrebbe non essere esattamente quello che stai cercando, ma esso può offrire alcune ulteriori idee.
http://www.sqlservercentral.com/articles/ Full-Text Search + + (2008) / 64248 /
Altri suggerimenti
Come implementare la risposta accettata utilizzando Net / C # / Entity Framework ...
-
Installa Ironia utilizzando NuGet.
-
Aggiungere la classe del campione da: http://irony.codeplex.com/SourceControl/latest#Irony .Samples / FullTextSearchQueryConverter / SearchGrammar.cs
-
Il codice scrivere in questo modo per convertire la stringa immessa dall'utente a una query.
var grammar = new Irony.Samples.FullTextSearch.SearchGrammar(); var parser = new Irony.Parsing.Parser(grammar); var parseTree = parser.Parse(userEnteredSearchString); string query = Irony.Samples.FullTextSearch.SearchGrammar.ConvertQuery(parseTree.Root);
-
Forse scrivere una stored procedure in questo modo:
create procedure [dbo].[SearchLivingFish] @Query nvarchar(2000) as select * from Fish inner join containstable(Fish, *, @Query, 100) as ft on ft.[Key] = FishId where IsLiving = 1 order by rank desc
-
Eseguire la query.
var fishes = db.SearchLivingFish(query);
Oltre a @ di Franzo risposta di cui sopra probabilmente anche desidera modificare il comportamento di arresto testi predefinito in SQL. In caso contrario, le query che contengono numeri a due cifre singoli (o altre parole stop) non prodotto risultati.
Si disabiliti parole stop, creare il proprio elenco di arresto parola e / o le parole di rumore impostato per essere trasformato come spiegato in SQL 2008: Disattivare parole comuni per il testo completo Ricercare
Per visualizzare l'elenco di sistema (in inglese) parole arrestare SQL, eseguire:
select * from sys.fulltext_system_stopwords where language_id = 1033
Mi rendo conto che è un po 'un side-passo dalla tua domanda iniziale, ma avete considerato allontanandosi da indici full-text SQL e usando qualcosa come Lucene / Solr invece?
Il modo più semplice per farlo è quello di utilizzare SQL dinamico (lo so, inserire le questioni di sicurezza qui) e rompere la frase in una stringa formattata correttamente.
È possibile utilizzare una funzione per rompere la frase in una variabile di tabella che è possibile utilizzare per creare la nuova stringa.
Una combinazione di GoldParser e Calitha dovrebbe ordinare qui fuori.
In questo articolo: http://www.15seconds.com/issue/070719.htm ha una classe googleToSql pure, che fa un po 'della traduzione per voi.