2012-04-28 18 views
1

我讀過,您可以排序搜索使用containstable以及SQL 2008服務器下包含和freetext的結果。我最近剛剛使用了freetext。自由文本分別循環遍歷單詞並與索引列進行比較。我希望能夠首先搜索短語,然後搜索單個單詞。使用containstable和自由文本搜索具有相關性排名

假設說明欄已編入索引。我使用一個存儲過程的查詢是這樣的:

SELECT id, description, item from table where (FREETEXT(description,@strsearch)) 

例,如果3行集包含的話,在他們的蘋果,我搜索「蘋果蛋糕」,該行設定ID2應該是第一個,那麼其他二者應遵循:

id1 apple pie 4/01/2012 
id2 apple cake 2/29/2011 
id3 candy apple 5/9/2011 

例,如果4行集包含在其中的食物的話,我搜索「快餐店」,該行設定的ID3應該是第一,其次是ID1(並不完全匹配,但因爲它在列中有'快餐'),那麼其他兩個應該如下:

id1 McDonalds fast food 
id2 healthy food 
id3 fast food restaurant 
id4 Italian restaurant 

回答

1

這篇文章有幫助嗎?

MSDN : Limiting Ranked Result Sets (Full-Text Search)

這意味着,在某種程度上,使用一個額外的參數,可以讓你的結果限制爲與最相關的那些(你可以影響使用WEIGHT),也爲了通過相關性(RANK )。

top_n_by_rank是一個整數值n,指定只有最高排名的匹配纔會按降序返回。

該文檔沒有示例FREETEXT;它只引用CONTAINSTABLE。但它肯定意味着CONTAINSTABLE輸出RANK列,您可以使用ORDER BY

我不知道是否有任何方法來執行您自己的定義的相關性。根據FTS排出前10位相關的匹配可能是有意義的,然後在輸出上應用您自己的排名,例如,你可以使用一個函數分割搜索條件,並按照匹配的詞數來排序。在下面的例子中,爲了簡單和容易複製,我沒有在子查詢中使用Full-Text,但可以將它替換爲您實際正在做的任何事情。首先創建功能:

IF OBJECT_ID('dbo.SplitStrings') IS NOT NULL 
    DROP FUNCTION dbo.SplitStrings; 
GO 
CREATE FUNCTION dbo.SplitStrings(@List NVARCHAR(MAX)) 
RETURNS TABLE 
AS 
    RETURN (SELECT Item FROM 
     (SELECT Item = x.i.value('(./text())[1]', 'nvarchar(max)') 
     FROM (SELECT [XML] = CONVERT(XML, '<i>' 
     + REPLACE(@List, ' ', '</i><i>') + '</i>').query('.') 
      ) AS a CROSS APPLY [XML].nodes('i') AS x(i)) AS y 
     WHERE Item IS NOT NULL 
    ); 
GO 

然後一個簡單的腳本顯示瞭如何進行匹配:

DECLARE @foo TABLE 
(
    id INT, 
    [description] NVARCHAR(450) 
); 

INSERT @foo VALUES 
(1,N'McDonalds fast food'), 
(2,N'healthy food'), 
(3,N'fast food restaurant'), 
(4,N'Italian restaurant'), 
(5,N'Spike''s Junkyard Dogs'); 

DECLARE @searchstring NVARCHAR(255) = N'fast food restaurant'; 

SELECT x.id, x.[description]--, MatchCount = COUNT(s.Item) 
FROM 
(
    SELECT f.id, f.[description] 
    FROM @foo AS f 

    -- pretend this actually does full-text search: 
    --where (FREETEXT(description,@strsearch)) 

    -- and ignore how I actually matched:  
    INNER JOIN dbo.SplitStrings(@searchstring) AS s 
    ON CHARINDEX(s.Item, f.[description]) > 0 

    GROUP BY f.id, f.[description] 
) AS x 
INNER JOIN dbo.SplitStrings(@searchstring) AS s 
ON CHARINDEX(s.Item, x.[description]) > 0 
GROUP BY x.id, x.[description] 
ORDER BY COUNT(s.Item) DESC, [description]; 

結果:

id description 
-- ----------- 
3 fast food restaurant 
1 McDonalds fast food 
2 healthy food 
4 Italian restaurant 
+0

非常感謝。從MSDN頁面和您的代碼中,您指出了正確的方向。然後我發現http://msdn.microsoft.com/en-us/library/aa172823%28v=sql.80%29.aspx有點混淆,但通過它工作 – Patriotec 2012-04-29 13:40:05

+0

@Aaron,使用2選擇的目的是什麼聲明。如果我註釋掉外部select語句並將order by子句移至內部select語句,我會得到相同的結果。 – iMatoria 2012-08-19 06:31:47