SQL Serverの全文検索
-
08-06-2019 - |
質問
現在、SQL Server データベースを備えたアプリケーションに取り組んでおり、人の名前を検索できる全文検索を機能させる必要があります。
現在、ユーザーは 3 つの異なる varchar 列を検索する名前フィールドに を入力できます。名、姓、ミドルネーム
次の情報を含む 3 行があるとします。
1 - フィリップ - J - フライ
2 - エイミー - NULL - ウォン
3 - レオ - NULL - ウォン
ユーザーが「Fry」などの名前を入力すると、行 1 が返されます。しかし、フィリップ・フライ、神父、フィルに入っても何も得られません。そしてなぜこんなことをするのか理解できません。Wong を検索すると 2 行目と 3 行目が取得され、Amy Wong を検索すると再び何も取得されません。
現在、クエリは CONTAINSTABLE を使用していますが、FREETEXTTABLE、CONTAINS、FREETEXT に切り替えましたが、結果に目立った違いはありません。テーブル メソッドは同じ結果を返しますがランク付けが行われるため、テーブル メソッドが推奨されます。
これがクエリです。
....
@Name nvarchar(100),
....
--""s added to prevent crash if searching on more then one word.
DECLARE @SearchString varchar(100)
SET @SearchString = '"'+@Name+'"'
SELECT Per.Lastname, Per.Firstname, Per.MiddleName
FROM Person as Per
INNER JOIN CONTAINSTABLE(Person, (LastName, Firstname, MiddleName), @SearchString)
AS KEYTBL
ON Per.Person_ID = KEYTBL.[KEY]
WHERE KEY_TBL.RANK > 2
ORDER BY KEYTBL.RANK DESC;
....
何か案は...?この全文検索が正しく機能しないのはなぜですか?
解決 3
ご回答いただきありがとうございます。ようやく動作させることができました。Biri と Kibbee の両方の回答の一部です。機能するには、文字列に * を追加し、スペースで区切る必要がありました。それで最終的に私は得ました
....
@Name nvarchar(100),
....
--""s added to prevent crash if searching on more then one word.
DECLARE @SearchString varchar(100)
--Added this line
SET @SearchString = REPLACE(@Name, ' ', '*" OR "*')
SET @SearchString = '"*'+@SearchString+'*"'
SELECT Per.Lastname, Per.Firstname, Per.MiddleName
FROM Person as Per
INNER JOIN CONTAINSTABLE(Person, (LastName, Firstname, MiddleName), @SearchString)
AS KEYTBL
ON Per.Person_ID = KEYTBL.[KEY]
WHERE KEY_TBL.RANK > 2
ORDER BY KEYTBL.RANK DESC;
....
さらに多くのフィールドが検索されています。質問のために単純化しただけです。申し訳ありませんが、回答に影響するとは思いませんでした。実際には、ニックネームの CSV を持つ列とメモ列も検索されます。
助けてくれてありがとう。
他のヒント
FreeTextTable は機能するはずです。
INNER JOIN FREETEXTTABLE(Person, (LastName, Firstname, MiddleName), @SearchString)
@SearchString には、「Phillip Fry」のような値が含まれている必要があります (スペースで区切られたすべての検索文字列を含む 1 つの長い文字列)。
Fr または Phil を検索したい場合は、アスタリスクを使用する必要があります。フィル*と神父*
「Phil」は正確に「Phil」という単語を探しています。「Phil*」は「Phil」で始まるすべての単語を検索します
人の名前を検索するだけの場合は、全文インデックスを使用しないほうがよい場合もあります。大きなテキスト フィールドがある場合にはフル テキスト インデックスは意味がありますが、フィールドごとに 1 つの単語を主に扱う場合は、フル テキスト インデックスからどれだけの追加情報が得られるかわかりません。新しいレコードを検索する前に、フルテキスト インデックスが自動的に再インデックスされるのを待つことは、多くの問題の 1 つである可能性があります。
次のようなクエリを作成するだけです。検索文字列をスペースで分割し、検索語のリストを作成します。
Select FirstName,MiddleName,LastName From person WHERE Firstname like @searchterm1 + '%' or MiddleName like @searchterm1 + '%' or LastName like @searchterm1 + '%' or Firstname like @searchterm2 + '%' etc....
別のアプローチは、個々のフィールドから検索を抽象化することです。
言い換えれば、データのビューを作成して、名、姓などのすべての分割フィールドを連結フィールドに変換します。フルネーム
次に、ビューで検索します。これにより、検索クエリがより単純になる可能性があります。
チェックしてみてはいかがでしょうか Lucene.net フルテキストの代替として。