簡體   English   中英

在SQL Server 2008中跨多個表,列使用全文搜索

[英]Using Full-Text Search in SQL Server 2008 across multiple tables, columns

我需要使用全文搜索從數據庫中的兩個表中搜索多個列。 有問題的兩個表都有相關的全文索引列。

我選擇全文搜索的原因:1。能夠輕松搜索重音詞(cafè)2。能夠按照詞語接近等排名.3。“你的意思是XXX?” 功能

這是一個虛擬表結構,以說明挑戰:

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)

我需要搜索書名,書注和作者姓名。

我知道有兩種方法可以做到這一點:

  1. 使用全文索引視圖:這可能是我首選的方法,但我不能這樣做,因為對於要進行全文索引的視圖,它需要是模式綁定的,沒有任何外連接,具有唯一索引。 我需要獲取我的數據的視圖不滿足這些約束(它包含我需要從中獲取數據的許多其他連接表)。

  2. 在存儲過程中使用連接 :這種方法的問題是我需要按排名排序結果。 如果我在表中進行多個連接,則默認情況下SQL Server不會跨多個字段進行搜索。 我可以在兩個鏈接表上組合兩個單獨的CONTAINS查詢,但我不知道從兩個搜索查詢中提取組合排名的方法。 例如,如果我搜索“Arthur”,則應考慮Book查詢和Author查詢的結果並相應地加權。

使用FREETEXTTABLE,您只需設計一些算法來計算每個連接表結果的合並排名。 下面的示例將結果傾向於書表中的命中。

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

請注意,我簡化了此示例的架構。

我遇到了和你一樣的問題,但它實際上涉及10個表(一個用戶表和其他幾個表的信息)

我在每個表的WHERE子句中使用FREETEXT進行了第一次查詢,但查詢耗時太長。

然后我看到幾個關於使用FREETEXTTABLE的回復,​​並檢查每個表的鍵列中的非空值,但這也需要很長時間才能執行。

我通過使用FREETEXTTABLE和UNION的組合來修復它:

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

事實證明這速度要快得多。

我希望它有所幫助。

我不認為接受的答案會解決問題。 如果您嘗試查找某位作者的所有書籍,並因此使用作者的姓名(或其中的一部分)作為搜索條件,則查詢返回的唯一書籍將是具有自己名稱的搜索條件的書籍。 。

我看到這個問題的唯一方法是復制你希望在Book表中搜索的作者列,並索引這些列(或列,因為它可能是聰明的將作者的相關信息存儲在本書的XML列中表)。

FWIW,在類似的情況下,我們的DBA創建了DML觸發器來維護專用的全文搜索表。 由於其許多限制,無法使用物化視圖。

我會使用存儲過程。 全文方法或其他任何返回排序,您可以排序。 我不確定他們將如何對抗彼此,但我相信你可能會修補一段時間並弄清楚。 例如:

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

這個答案已經過期了,但是如果你不能修改主表,一種方法是創建一個新表,並將搜索參數添加到一列。

然后在該列上創建一個全文索引並查詢該列。

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

在上面的代碼[EAN]。[dbo]。[tblEanFullTextSearch]中,FullTextSearchColumn是添加了字段的新表和列,您現在可以對新表進行查詢,並在表中添加要顯示數據的表。

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM