使用全文检索SQL Server2008年在多个表格,列
-
03-07-2019 - |
题
我需要搜索多个列两个表格在我的数据库,使用全文搜索。这两个表中的问题有关列全文编制索引。
我之所以选择进行全文搜索:1.能够搜索饰词容易(咖啡) 2.能够秩根据字接近,等等。3."你的意思是XXX?"功能
这里是一个 伪 表结构,以说明的挑战:
表本书 BookID Name (Full-text indexed) Notes (Full-text indexed) 表架 ShelfID BookID 表ShelfAuthor AuthorID ShelfID 表作者 AuthorID Name (Full-text indexed)
我需要搜索整个书名书记和作者姓名。
我知道两种方式实现此目的:
使用全文检索查看: 这将是我的首选方法,但是我不能这样做,是因为用于为可全文检索的,它需要schemabound,没有任何外连接,有一个独特的索引。看我将需要得到我的数据不满足这些制约因素(这包含许多其他加入了表格,我需要得到数据)。
使用同一个储存程序:这种方法的问题是,我需要有结果按等级。如果我多加入跨越所表、SQL服务器不会搜索跨多个领域的默认。我可以结合两个含有查询关于在两个相联系的表格,但是我不知道的一种方法来提取的 相结合 排名从两个搜索查询。例如,如果我寻找亚瑟,结果这本书的查询者查询时应考虑和加权。
解决方案
使用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(一个用户表和其他几个人,为信息)
我做了我的第一个查询使用一般在其条款用于每个表,但查询是把时间太长了。
然后我看到几个答复关于使用FREETEXTTABLE而不是检查和对不null值的关键列每个表格,但是这花了还长到执行。
我固定使用一个组合FREETEXTTABLE和联盟的选择:
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是添加了字段的新表和列,现在可以对新表进行查询,并连接到要显示的表来自的数据。
希望这有帮助