2012-04-28 6 views
1

SQL 2008サーバーの下にcontainsとfreetextと共にcontainstableを使用して検索結果をランク付けすることができます。私は最近、初めてフリーテキストを使用しました。フリーテキストは単語を別々にループし、索引付けされた列と比較します。私はフレーズを最初に検索し、その後は単一の単語を検索できるようにしたい。containstableとfreetextを使用して関連性の高い順で検索

説明列にインデックスが設定されているとします。私はこのようなストアドプロシージャのクエリ使用しています:

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(ない完全な一致が続くが、列に「ファーストフード」があるため)、他の2つは続く必要があります。

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

答えて

1

この記事は役に立ちますか?

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

それはRANK(追加パラメータを使用すると、あなたは(あなたがWEIGHTを使用して影響を与えることができます)最大の関連性をものに結果を制限し、また、その関連性によって注文できるようになると、一部では、意味)。

top_n_by_rankのみN 最高ランクマッチが降順で、返されることを指定する、整数値である、N。

FREETEXTの例はありません。 CONTAINSTABLEのみを参照します。しかし、間違いなくCONTAINSTABLERANKという列を出力し、ORDER BYに使用できることを意味します。

関連性の独自定義を実施する方法があるかどうかわかりません。 FTSに従って上位10の関連性のあるマッチを抜き出し、自分のランキングを出力に適用するとよいでしょう。関数を使って検索用語を分割し、一致した単語の数だけ並べ替えることができます。次の例では、単純化と簡単なreproのために、サブクエリでフルテキストを使用していませんが、実際に行っているものと置き換えることができます。そして、マッチングを実行する方法を示して簡単なスクリプト

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

+0

@Aaron、2を使用する目的は何ですかselectステートメント。外側のselect文をコメントアウトし、order by節を内側のselect文に移動すると、同じ結果が得られます。 – iMatoria

関連する問題