2011-10-10 14 views
5

ha problema con la e commerciale (&)SQL Server Full Text Search e commerciale (&)

Come cercare le parole (o frasi) che contengono una e commerciale (&).

Per esempio, nel database sono:

1: "Johnson & Johnson" 
2: "AT&T" 
3: "Sample & Sample" 

Come devo scrivere un testo completo della query di ricerca per la ricerca di singoli record?

SELECT * from Companies c WHERE CONTAINS(c.CompanyName, '"AT&T"') 

So quel personaggio (&) è responsabile per l'operazione logica AND. Ma non so come codificarlo per cercare nel testo con la ricerca full text.

Qualche idea?

risposta

5

Versione corta: Non è possibile (o almeno si può, ma si può ottenere più risultati del previsto)

Versione lunga: Il carattere '&' è trattata come un "word breaker" , cioè quando SQL Server incontra un '&' lo considera come l'inizio di una nuova "parola" (cioè token). Cosa rileva SQL Server durante l'analisi di "AT&T" è di due token, "AT" e "T".

È possibile controllare questo per voi stessi usando sys.dm_fts_parser:

SELECT * FROM sys.dm_fts_parser('AT&T', 1033, 0, 0) 

keyword  group_id phrase_id occurrence special_term display_term expansion_type source_term 
----------- ----------- ----------- ----------- ------------- ------------- -------------- ----------- 
0x00610074 1   0   1   Noise Word at   0    AT 
0x0074  2   0   1   Noise Word t    0    T 

Ciò significa che la ricerca per "AT&T" è più o meno esattamente la stessa solo alla ricerca di "AT T".

Questo è di progettazione, per quanto posso vedere l'unico modo per modificare questo comportamento sarebbe quello di installare il proprio word breaker, tuttavia questo non è qualcosa che consiglierei di fare.

2

La risposta accettata non è interamente corretta. Racchiudere il termine di ricerca tra virgolette rende il raggruppamento di parole una "frase" corrispondente. In questo caso, gli ampsers e (&) possono essere trattati come un carattere letterale, ad esempio quando sono circondati da una o più lettere che non formano una parola conosciuta. Basta guardare il tuo "AT&T" esempio, vediamo:

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"AT&T"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 
GO 

Returns:

keyword    group phrase occurrence special  display expansion source 
        id  id     term   term  type  term 
0x0061007400260074 1  0  1   Exact Match at&t  0   AT&T 

Come si può vedere, la e commerciale non presenta alcun problema a tutti, fino a quando è racchiuso tra virgolette (") che stai già facendo, woo hoo!

Tuttavia, che non funziona in modo pulito per il "Johnson & Johnson" esempio

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"Johnson & Johnson"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 
GO 

Returns:

keyword       group phrase occurrence special  display expansion source 
           id  id     term   term  type  term 
0x006A006F0068006E0073006F006E 1  0  1   Exact Match johnson 0   Johnson & Johnson 
0x006A006F0068006E0073006F006E 1  0  2   Exact Match johnson 0   Johnson & Johnson 

che sembrerebbe corrispondere anche un termine di ricerca di Johnson Johnson, che non è tecnicamente corretto.

Così, oltre a racchiudere fra virgolette, è possibile anche convertire la e commerciale per essere un carattere di sottolineatura (_) che viene gestito in modo diverso:

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"Johnson _ Johnson"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 
GO 

Ritorni:

keyword       group phrase occurrence special  display expansion source 
           id  id     term   term  type  term 
0x006A006F0068006E0073006F006E 1  0  1   Exact Match johnson 0   Johnson _ Johnson 
0x005F       1  0  2   Exact Match _  0   Johnson _ Johnson 
0x006A006F0068006E0073006F006E 1  0  3   Exact Match johnson 0   Johnson _ Johnson 

E , facendo quella traduzione di carattere non sembra influenzare negativamente la ricerca originale "AT&T":

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"AT_T"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 

Resi:

keyword    group phrase occurrence special  display expansion source 
        id  id     term   term  type  term 
0x00610074005F0074 1  0  1   Exact Match at_t  0   AT_T 
Problemi correlati