私がこの質問を繰り返さないことを願っています。ここに投稿する前に、ここで検索してグーグルで検索しました。
フルテキストを有効にしてSQL Server 2008R2でeStoreを実行しています。
ハイブリッドフルテキストを使用しており、通常のように検索を行っています。これにより、より適切な結果が得られます。一時テーブルおよびDISTINCTに対して実行されたすべてのクエリが返されました。
マッチングロジック
次のSQLを実行して、フルテキストを使用して関連製品を取得します。ただし、@ Keywordsは前処理されます。 「CLC 2200」が「CLC * AND 2200 *」に変更されるとします。
Dbo.Product WHERE CONTAINS(TextSearch、@ Keywords)からIDを選択
別のクエリが通常のように実行されます。したがって、「CLC 2200」は「%clc%のようなTextSearch AND%2200%のようなTextSearch」に前処理されます。これは、全文検索ではキーワードの前にパターンが検索されないためです。たとえば、「pclc 2200」は返されません。
DboからIDを選択します。製品WHERE TextSearch like '%clc%' AND TextSearch like '%2200%'
手順1と2でレコードが返されなかった場合は、次の検索が実行されます。値135は、より関連性の高いレコードを返すように微調整されました。
Dbo.Productからp.idを選択し、p INNER JOIN FREETEXTTABLE(product、TextSearch、@ Keywords)AS r ON p.Id = r。[KEY] WHERE r.RANK> 135
上記のすべてを組み合わせると、妥当な速度で問題なく機能し、キーワードに関連する製品が返されます。
しかし、製品がまったく見つからない場合は、さらに改善したいと考えています。
お客様が「CLC 2200npk」を探していて、この製品がなかった場合、「CLC 2200」のすぐ隣に表示する必要があったとします。
これまでのところ、Soundex()関数を使用してみました。 TextSearch列の各単語のsoundex値を計算し、キーワードのsoudex値と比較して購入します。しかし、これは非常に多くのレコードを返し、あまりにも遅くなります。
たとえば、「CLC 2200npk」は「CLC 1100」などの製品を返します。ただし、これは良い結果ではありません。 CLC 2200npkに近くないため
別の良いものがあります here 。ただし、これはCLR関数を使用します。しかし、サーバーにCLR関数をインストールできません。
だから私の論理は
'CLC 2200npk'が見つからない場合は 'CLC 2200'で閉じるを表示 'CLC 2200'が見つからない場合は 'CLC 1100'で次に閉じるを表示
ありがとう。
かなり迅速なドメイン固有のソリューションは、SOUNDEXと2つの文字列間の数値距離を使用して文字列の類似性を計算することです。これは、多くの製品コードがある場合にのみ役立ちます。
以下のような単純なUDFを使用して、文字列から数値文字を抽出できるため、「CLC 2200npk」から2200を取得し、「CLC 1100」から1100を取得できるため、各入力のSOUNDEX出力に基づいて近さを判断できます。各入力の数値コンポーネントの近さと同様。
CREATE Function [dbo].[ExtractNumeric](@input VARCHAR(1000))
RETURNS INT
AS
BEGIN
WHILE PATINDEX('%[^0-9]%', @input) > 0
BEGIN
SET @input = STUFF(@input, PATINDEX('%[^0-9]%', @input), 1, '')
END
IF @input = '' OR @input IS NULL
SET @input = '0'
RETURN CAST(@input AS INT)
END
GO
汎用アルゴリズムに関する限り、データセットのサイズとパフォーマンスの要件に応じて、成功の度合いを変えるのに役立ついくつかの方法があります。 (両方のリンクでTSQL実装が利用可能です)
ここ は、両方のアルゴを一緒に適用する興味深い記事であり、いくつかのアイデアを提供します。
うまくいけば、それのいくつかが少し役立つでしょう。
編集: ここ は、はるかに高速な部分レーベンシュタイン距離の実装です(投稿を読んで、通常のものとまったく同じ結果は返されません)。 125000行のテストテーブルでは、6秒で実行されましたが、最初にリンクしたものは60秒でした。