Domanda

Devo cercare tra più colonne da due tabelle nel mio database usando la ricerca full-text. Le due tabelle in questione hanno le colonne pertinenti indicizzate full-text.

Il motivo per cui sto optando per la ricerca full-text: 1. Essere in grado di cercare facilmente parole accentate (caf & # 232;) 2. Essere in grado di classificare in base alla vicinanza della parola, ecc. 3. "Intendevi XXX?" funzionalità

Ecco una struttura fittizia per illustrare la sfida:

Table Book
BookID
Name (Full-text indexed)
Notes (Full-text indexed)

Table Shelf
ShelfID
BookID

Table ShelfAuthor
AuthorID
ShelfID

Table Author
AuthorID
Name (Full-text indexed)

Devo cercare tra Nome libro, Note libro e Nome autore.

Conosco due modi per raggiungere questo obiettivo:

  1. Uso di una vista indicizzata full-text: questo sarebbe stato il mio metodo preferito, ma non posso farlo perché una vista deve essere indicizzata full-text, è necessario essere schemabound, non avere alcun join esterno, avere un indice univoco. La vista di cui avrò bisogno per ottenere i miei dati non soddisfa questi vincoli (contiene molte altre tabelle unite di cui ho bisogno per ottenere i dati).

  2. Uso dei join in una procedura memorizzata : il problema con questo approccio è che devo disporre i risultati in ordine di classificazione. Se sto effettuando più join tra le tabelle, per impostazione predefinita SQL Server non cercherà tra più campi. Posso combinare due singole query CONTAINS sulle due tabelle collegate, ma non conosco un modo per estrarre il rango combinato dalle due query di ricerca. Ad esempio, se cerco "Arthur", i risultati sia della query Libro che della query Autore dovrebbero essere presi in considerazione e ponderati di conseguenza.

È stato utile?

Soluzione

Usando FREETEXTTABLE, devi solo progettare un algoritmo per calcolare il grado unito su ogni risultato della tabella unita. L'esempio seguente inclina il risultato verso i colpi dal tavolo del libro.

SELECT b.Name, a.Name, bkt.[Rank] + akt.[Rank]/2 AS [Rank]
FROM Book b
INNER JOIN Author a ON b.AuthorID = a.AuthorID
INNER JOIN FREETEXTTABLE(Book, Name, @criteria) bkt ON b.ContentID = bkt.[Key] 
LEFT JOIN FREETEXTTABLE(Author, Name, @criteria) akt ON a.AuthorID = akt.[Key]
ORDER BY [Rank] DESC

Nota che ho semplificato il tuo schema per questo esempio.

Altri suggerimenti

Ho avuto lo stesso problema, ma in realtà riguardava 10 tabelle (una tabella Users e molte altre per informazione)

Ho eseguito la mia prima query utilizzando FREETEXT nella clausola WHERE per ogni tabella ma la query impiegava troppo tempo.

Ho quindi visto diverse risposte sull'utilizzo di FREETEXTTABLE e sul controllo dei valori non nulli nella colonna chiave per ogni tabella, ma ciò ha richiesto troppo tempo per essere eseguito.

L'ho risolto usando una combinazione di FREETEXTTABLE e UNION seleziona:

SELECT Users.* FROM Users INNER JOIN
(SELECT Users.UserId FROM Users INNER JOIN FREETEXTTABLE(Users, (column1, column2), @variableWithSearchTerm) UsersFT ON Users.UserId = UsersFT.key
UNION
SELECT Table1.UserId FROM Table1 INNER JOIN FREETEXTTABLE(Table1, TextColumn, @variableWithSearchTerm) Table1FT ON Table1.UserId = Table1FT.key
UNION
SELECT Table2.UserId FROM Table2 INNER JOIN FREETEXTTABLE(Table2, TextColumn, @variableWithSearchTerm) Table2FT ON Table2.UserId = Table2FT.key
... --same for all tables
) fts ON Users.UserId = fts.UserId

Questo si è rivelato incredibilmente molto più veloce.

Spero che sia d'aiuto.

Non credo che la risposta accettata risolverà il problema. Se provi a trovare tutti i libri di un determinato autore e, quindi, usi il nome dell'autore (o parte di esso) come criterio di ricerca, gli unici libri restituiti dalla query saranno quelli che hanno i criteri di ricerca con il proprio nome .

L'unico modo in cui vedo questo problema è replicare le colonne dell'autore per le quali si desidera cercare nella tabella del libro e indicizzare quelle colonne (o colonna poiché sarebbe probabilmente intelligente archiviare le informazioni rilevanti dell'autore in una colonna XML nella tabella del libro).

FWIW, in una situazione simile il nostro DBA ha creato trigger DML per mantenere una tabella di ricerca full-text dedicata. Non è stato possibile utilizzare una vista materializzata a causa delle sue numerose restrizioni.

Vorrei usare una procedura memorizzata. Il metodo di testo completo o altro restituisce un rango che è possibile ordinare. Non sono sicuro di come saranno ponderati l'uno contro l'altro, ma sono sicuro che potresti armeggiare per un po 'e capirlo. Ad esempio:

Select SearchResults.key, SearchResults.rank From FREETEXTTABLE(myColumn, *, @searchString) as SearchResults Order By SearchResults.rank Desc

Questa risposta è in ritardo, ma un modo per farlo se non è possibile modificare le tabelle primarie è creare una nuova tabella con i parametri di ricerca aggiunti a una colonna.

Quindi crea un indice di testo completo su quella colonna e interroga quella colonna.

Esempio

SELECT 
    FT_TBL.[EANHotelID]                 AS HotelID, 
    ISNULL(FT_TBL.[Name],'-')           AS HotelName,
    ISNULL(FT_TBL.[Address1],'-')       AS HotelAddress,
    ISNULL(FT_TBL.[City],'-')           AS HotelCity,
    ISNULL(FT_TBL.[StateProvince],'-')  AS HotelCountyState,
    ISNULL(FT_TBL.[PostalCode],'-')     AS HotelPostZipCode,
    ISNULL(FT_TBL.[Latitude],0.00)      AS HotelLatitude,
    ISNULL(FT_TBL.[Longitude],0.00)     AS HotelLongitude,
    ISNULL(FT_TBL.[CheckInTime],'-')    AS HotelCheckinTime,
    ISNULL(FT_TBL.[CheckOutTime],'-')   AS HotelCheckOutTime,
    ISNULL(b.[CountryName],'-')         AS HotelCountry,
    ISNULL(c.PropertyDescription,'-')   AS HotelDescription,
    KEY_TBL.RANK 

    FROM [EAN].[dbo].[tblactivepropertylist] AS FT_TBL INNER JOIN
     CONTAINSTABLE ([EAN].[dbo].[tblEanFullTextSearch], FullTextSearchColumn, @s)
      AS KEY_TBL
    ON FT_TBL.EANHotelID = KEY_TBL.[KEY]
    INNER JOIN [EAN].[dbo].[tblCountrylist] b
    ON FT_TBL.Country = b.CountryCode
    INNER JOIN [EAN].[dbo].[tblPropertyDescriptionList] c
    ON FT_TBL.[EANHotelID] = c.EANHotelID

Nel codice sopra [EAN]. [dbo]. [tblEanFullTextSearch], FullTextSearchColumn è la nuova tabella e colonna con i campi aggiunti, ora puoi eseguire una query sulla nuova tabella con join alla tabella che desideri visualizzare i dati da.

Spero che questo aiuti

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top