2009-02-03 9 views
11

Qual è il modo migliore per convertire i termini di ricerca inseriti da un utente, in una query che può essere utilizzato in una clausola in cui per la ricerca full-text interrogare una tabella e ottenere risultati rilevanti? Ad esempio, la seguente query immessa dall'utente:Conversione inserito dall'utente query di ricerca in cui la clausola per l'uso in ricerca full-text di SQL Server

+"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"')) 

sto usando un query parser class in questo momento, che analizza la query inserite dagli utenti in token utilizzando un'espressione regolare e quindi costruisce la clausola where dai token.

Tuttavia, dato che questo è probabilmente un requisito comune in molti sistemi che utilizzano la ricerca full-text, sono curioso di sapere come altri sviluppatori hanno affrontato questo problema e se esiste un modo migliore di fare le cose.

risposta

5

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/

+0

L'ho provato e non è poi così bello. –

+2

NB: l'articolo richiede la registrazione e l'iscrizione a una newsletter (quindi non è un problema se si può sopportare una cosa del genere) –

+0

Questo funziona bene. Puoi vedere come implementarlo di seguito. – franzo

0

Mi rendo conto che si tratta di un passo secondario rispetto alla domanda iniziale, ma avete preso in considerazione l'idea di abbandonare gli indici di fulltext SQL e utilizzare invece qualcosa come Lucene/Solr?

+0

Sì, mi piacerebbe trasferirmi a Lucene ad un certo punto, anche se l'ho toccato in passato e anche se impostare le basi è relativamente semplice, facendolo fare lo stesso tipo di cose che sto facendo ora è un po 'più di lavoro, quindi l'ho messo in attesa. – Mun

0

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.

7

Come implementare la risposta accettata utilizzando Net/C#/Entity Framework ...

  1. Installare Ironia utilizzando NuGet.

  2. aggiungere la classe del campione da: http://irony.codeplex.com/SourceControl/latest#Irony.Samples/FullTextSearchQueryConverter/SearchGrammar.cs

  3. codice Scrivi come questo 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); 
    
  4. Forse scrivere una stored procedure come questa:

    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 
    
  5. eseguire la query.

    var fishes = db.SearchLivingFish(query); 
    
1

Oltre a @ di Franzo risposta di cui sopra probabilmente anche voler modificare il comportamento stop word impostazione predefinita in SQL. In caso contrario, le query contenenti numeri a cifra singola (o altre parole di arresto) non restituiranno alcun risultato.

Si disabiliti parole stop, creare la tua selezione arresto parola e/o di parole non significative impostati per essere trasformato come spiegato nella SQL 2008: Turn off Stop Words for Full Text Search Query

Per visualizzare l'elenco sistema (inglese) parole arrestare SQL, eseguire:

select * from sys.fulltext_system_stopwords where language_id = 1033