我对全文搜索很陌生,我真的很想知道在多个不相关的表中执行“站点搜索”样式全文搜索的最佳方法(我计划在 4 个表中执行此操作)。我正在考虑使用这样的视图:
CREATE VIEW [dbo].[Search] WITH SCHEMABINDING
AS
SELECT p.ProductId AS ItemId
,'Product' AS ItemType
,p.Title AS ItemTitle
,p.LongDescription AS LongDescription
,p.Price AS Price
FROM dbo.Product AS p
WHERE p.IsActive = 1
UNION
SELECT a.ArticleId AS ItemId
,'Article' AS ItemType
,a.ArticleTitle AS ItemTitle
,a.Contents AS LongDescription
,NULL AS Price
FROM dbo.Article AS a
WHERE a.IsActive = 1
但是在研究索引的正确语法时,我意识到“a”我需要一个唯一索引,而“b”显然不能使用 Unions 视图来创建全文索引......
我看到的另一种方法是为每个表创建一个 FTI,然后在存储过程中,将它们联合到一个 tmp 表中,然后选择具有 Order By 等级的 tmp 表。
我真的很感激这方面的一些指导,我发现的大部分内容都与多个相关表有关,在这些表中加入一个视图就足以解决这个问题。
编辑:
@Joe 好心地回答了这个我已经忘记并实际上以某种方式解决的问题,但担心它有点啰嗦,似乎这可能是他建议的两种方式中最合乎逻辑的,这就是我我正在使用 - 我完全忘记了我必须将它分页到......我认为客户不会对无穷无尽的结果列表感到兴奋......
我的一位同事还提出了他见过的另一种技术,即在表中抛出元数据,然后将结果缓存在另一个表中,然后在该表中进行全文搜索,如果你知道你的元数据将是另外的,您还需要将其键入原始表格以立即或显示实际结果(如果需要的话,可以说全文)
CREATE PROCEDURE [dbo].[up_Search]
@Term VARCHAR(100)
,@Skip INT = 0
,@Take INT = 10
AS
DECLARE @Search TABLE
(
ItemId INT
,ItemType VARCHAR(50)
,ItemTitle VARCHAR(100)
,LongDescription VARCHAR(MAX)
,Price DECIMAL(10,2)
,SearchRank INT
)
INSERT INTO @Search SELECT * FROM (
SELECT p.ProductId AS ItemId
,'Product' AS ItemType
,p.Title AS ItemTitle
,p.LongDescription AS LongDescription
,p.Price AS Price
,KEY_TBL.RANK AS SearchRank
FROM dbo.Product AS p
INNER JOIN CONTAINSTABLE(dbo.Product, Title, @Term) AS KEY_TBL ON p.ProductId = KEY_TBL.[KEY]
WHERE p.IsActive = 1
UNION
SELECT a.ArticleId AS ItemId
,'Article' AS ItemType
,a.ArticleTitle AS ItemTitle
,a.Contents AS LongDescription
,NULL AS Price
,KEY_TBL.RANK AS SearchRank
FROM dbo.Article AS a
INNER JOIN CONTAINSTABLE(dbo.Article, ArticleTitle, @Term) AS KEY_TBL ON a.ArticleId = KEY_TBL.[KEY]
WHERE a.IsActive = 1
UNION
SELECT n.NewsId AS ItemId
,'News' AS ItemType
,n.NewsTitle AS ItemTitle
,n.Contents AS LongDescription
,NULL AS Price
,KEY_TBL.RANK AS SearchRank
FROM dbo.News AS n
INNER JOIN CONTAINSTABLE(dbo.News, NewsTitle, @Term) AS KEY_TBL ON n.NewsId = KEY_TBL.[KEY]
WHERE n.IsActive = 1
UNION
SELECT b.BusinessId AS ItemId
,bt.Title AS ItemType
,b.Title AS ItemTitle
,b.LongDescription AS LongDescription
,NULL AS Price
,KEY_TBL.RANK AS SearchRank
FROM dbo.Business AS b
INNER JOIN CONTAINSTABLE(dbo.Business, Title, @Term) AS KEY_TBL ON b.BusinessId = KEY_TBL.[KEY]
INNER JOIN dbo.BusinessType AS bt ON b.BusinessTypeId = bt.BusinessTypeId
WHERE b.IsActive = 1
) AS tmp;
WITH SearchCT AS
(
SELECT ItemId
,ItemType
,ItemTitle
,LongDescription
,Price
,SearchRank
,ROW_NUMBER() OVER (ORDER BY SearchRank DESC) AS RowNumber
,COUNT(*) OVER () AS RecordCount
FROM @Search
)
SELECT ItemId, ItemType, ItemTitle, LongDescription, SearchRank, RowNumber, RecordCount
FROM SearchCT
WHERE RowNumber BETWEEN @Skip + 1 AND (@Skip + @Take)
ORDER BY RowNumber
返回 0