Frage

Ich brauche über mehrere Spalten aus zwei Tabellen in meiner Datenbank mit Volltextsuche zu suchen. Die beiden Tabellen in Frage haben die relevanten Spalten volltextindiziert.

Der Grund, warum ich mich für die Entscheidung Volltextsuche: 1. Um leicht akzentuierten Worte suchen (CAFE) 2. Um in der Lage sein Wort Nähe Rang nach etc. 3. „Hast du XXX bedeuten?“ Funktionalität

Hier ist ein Dummy Tabellenstruktur, um die Herausforderung zu veranschaulichen:

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)

Ich brauche über Buch-Namen, Buch Notes und Namen des Autors.

suchen

Ich kenne zwei Möglichkeiten, dies zu tun:

  1. Mit einer Volltext indizierte Sicht: Das ist meine bevorzugte Methode gewesen wäre, aber ich kann das nicht tun, weil für eine Ansicht Volltext-indiziert wird, muss es schemabound werden, haben keine Outer-Joins, haben einen eindeutigen Index. Die Ansicht, die ich benötigen, um meine Daten nicht über diese Einschränkungen erfüllen (es viele andere verknüpften Tabellen enthält ich brauche, um Daten aus).

  2. Verwendung in einer gespeicherten Prozedur verbindet : Das Problem bei diesem Ansatz ist, dass ich die Ergebnisse nach Rang sortiert haben muß. Wenn ich mache mehrere über die Tabellen verknüpft, SQL Server wird nicht über mehrere Felder standardmäßig suchen. Ich kann kombinieren zwei einzelne ENTHÄLT Anfragen an den beiden verknüpften Tabellen, aber ich weiß nicht, von einer Art, die kombiniert Rang von den beiden Suchanfragen zu extrahieren. Zum Beispiel, wenn ich für ‚Arthur‘ zu suchen, die Ergebnisse sowohl der Buchabfrage und der Autor Abfrage sollte entsprechend berücksichtigt und gewichtet genommen werden.

War es hilfreich?

Lösung

Mit FREETEXTTABLE, müssen Sie nur einige Algorithmus zu entwerfen, das fusionierte Rang auf jedem verbundenen Tabelle Ergebnis zu berechnen. Das folgende Beispiel führt zu einer Verzerrung Ergebnis zu Hits aus dem Büchertisch.

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

Beachten Sie, dass ich Ihr Schema für dieses Beispiel vereinfacht.

Andere Tipps

Ich hatte das gleiche Problem wie du, aber es beteiligt tatsächlich 10 Tabellen (eine Tabelle Benutzer und einige andere Informationen)

habe ich meine erste Abfrage mit FREETEXT- in der WHERE-Klausel für jede Tabelle, aber die Abfrage nahm viel zu lang.

Ich sah dann mehrere Antworten über die Verwendung von FREETEXTTABLE statt und Überprüfung für nicht Werte in der Schlüsselspalte für jede Tabelle nullt, aber das dauerte auch lange auszuführen.

Ich reparierte es durch eine Kombination von FREETEXTTABLE verwenden und UNION wählt:

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

Dies erwies sich als unglaublich viel schneller sein.

Ich hoffe, es hilft.

Ich glaube nicht, die akzeptierte Antwort, das Problem zu lösen. Wenn Sie versuchen, alle Bücher von einem bestimmten Autor zu finden, und deshalb verwenden den Namen des Autors (oder ein Teil davon) als die Suchkriterien, die nur von der Abfrage zurück Bücher werden diejenigen sein, die die Suchkriterien im eigenen Namen haben .

Die einzige Art, wie ich, um dieses Problem zu sehen ist der Autor Spalten zu replizieren, die Sie mögen die Spalten suchen, indem Sie in den Buch von Tabellen und Indizes (oder Spalte, da es wahrscheinlich der Autors relevante Informationen in einer XML-Spalte zu speichern wäre klug im Buch Tabelle).

FWIW, in einer ähnlichen Situation unsere DBA erstellt DML löst eine spezielle Volltextsuche Tabelle zu halten. Es war nicht möglich, eine materialisierte Ansicht zu verwenden, wegen seiner vielen Einschränkungen.

Ich würde eine gespeicherte Prozedur verwenden. Die Volltext-Methode oder was auch immer gibt einen Rang, den Sie sortieren können. Ich bin nicht sicher, wie sie gegen sie gewichtet werden, aber ich bin sicher, dass Sie für eine Weile basteln konnten und es herausfinden. Zum Beispiel:

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

Diese Antwort ist auch überfällig, aber eine Möglichkeit, dies zu tun, wenn Sie nicht primäre Tabellen ändern können, ist es, eine neue Tabelle mit den Suchparametern zu einer Spalte hinzugefügt zu erstellen.

Dann einen Volltextindex für die Spalte erstellen und diese Spalte abgefragt werden.

Beispiel:

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

In dem obigen Code [EAN]. [Dbo]. [TblEanFullTextSearch], FullTextSearchColumn ist die neue Tabelle und die Spalte mit den Feldern hinzugefügt haben, können Sie nun eine Abfrage auf der neuen Tabelle nicht mit an den Tisch verbindet Sie anzeigen möchten die Daten aus.

Hope, das hilft

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top