web-dev-qa-db-ja.com

FullTextSearchインデックス作成/特殊文字を含む単語の検索

FullTextSearchインデックス付き列にハッシュタグをクエリしようとしています

SELECT Bio FROM Users
WHERE CONTAINS (Bio,'promoter')

SELECT Bio FROM Users
WHERE CONTAINS (Bio,'#promoter')

両方の結果が同じレコードを返す

promoter of #Art

検索語"#promoter"も二重引用符で囲みましたが、結果は同じでした。

'@something'を検索すると同じ問題が発生します

FullTextSearchで特殊文字にインデックスを付けるために何をする必要がありますか?

4
Nikola Mitev

うーん、「#」は句読点として数えられると思います。SQLServerフルテキストインデックスはTwitterより先に発明されました。ただし、いくつかのアプローチがあります。

1)前処理

全文関数を使用してデータのmostをフェッチし、次にLikeでデータを絞り込みます。たとえば、

SELECT Id
INTO #tmp
FROM dbo.Users
WHERE CONTAINS ( Bio, '#promoter' )

SELECT *
FROM dbo.Users u
WHERE u.Bio Like '%#promoter%'
AND EXISTS ( SELECT * FROM #tmp t WHERE u.Id = t.Id )

CONTAINSTABLEを使用して1つのクエリで同じことを行うことはできますが、必ずしも計画の順序を保証することはできません。なぜT-SQLが宣言型であるかを保証することはできません。私は明示的にすることを好みますが、パフォーマンスが許容可能であるか、データ量が少ない場合は、2つを組み合わせてください。

SELECT *
FROM dbo.Users u
    INNER JOIN CONTAINSTABLE ( Users, Bio, '"#promoter"' ) ct ON u.Id = ct.[key]
WHERE u.Bio Like '%#promoter%'

100万行のテーブルでいくつかの簡単なテストを行ったところ、問題なく動作したようです。 YMMV。

2)列のトークン化されたバージョン

代替バージョンを格納します。たとえば、次のように、「#」がリテラルテキスト「ハッシュタグ」に置き換えられた計算列:

-- Add computed column
ALTER TABLE dbo.Users ADD cleanBio AS REPLACE ( Bio, '#', 'hashtag' )

-- Add the computed column to full-text index
ALTER FULLTEXT INDEX ON dbo.Users ADD ( cleanBio ) 
GO

SELECT * FROM dbo.Users
WHERE CONTAINS ( cleanBio, 'hashtagpromoter' )

ここには明らかにストレージのオーバーヘッドがあります。

あなたのデータを使ってこれらのアプローチを試すことを検討し、どのように進んだかを私に知らせてください。

5
wBob