2008-08-19 28 views
12

私は現在、SQLサーバデータベースを持っているアプリケーションを開発中です。人々の名前を検索できる完全なテキスト検索が必要です。SQL Serverの全文検索

現在、ユーザーは3つの異なるvarchar colを検索する名前フィールドにaを入力できます。最初、最後、中間の名前

私は次の情報で3行があると言う。

1 - フィリップ - J - フライ

2 - エイミー - NULL - ウォン

3 - レオ - NULL - ウォン

ユーザは、 'フライ' と名前を入力した場合には、うしかし、彼らがフィリップ・フライ(Phillip Fry)、またはフィル(Fr)、またはフィル(Phil)に入ると、何も得られません。もし彼らがWongを検索すると、Amy Wongを検索すると2行目と3行目になり、何も得られません。

現在、クエリでは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 = '"'[email protected]+'"' 
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 = '"*'[email protected]+'*"' 

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とメモ列も持つ列を検索します。

ありがとうございました。

+0

ワイルドカード文字としてのアスタリスクは、検索語の** end **で使用する場合にのみ機能することに注意してください。検索語の先頭にあるアスタリスクは、全文検索エンジンによって単純に無視されます。 – RSW

+0

答えをありがとう。あなたはリラとベンダーを忘れた。 Luceneを使うことはできますか? –

4

FreeTextTableが動作するはずです。

INNER JOIN FREETEXTTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) 

@SearchStringは、(スペースで区切られた検索文字列のすべてを含む1つの長い文字列)「フィリップ・フライ」のような値が含まれている必要があります。

あなたは神父やフィルを検索したい場合は、アスタリスクを使用する必要があります。フィル*およびFR *

「フィル」は、正確に単語「フィル」を探しています。 「Phil *」は「Phil」で始まるすべての単語を探しています

4

人の名前を検索するだけであれば、全文索引を使用しないことも可能です。大きなテキストフィールドがあるときは、フルテキストインデックスは意味がありますが、フィールドごとに1単語を主に扱う場合は、フルテキストインデックスからどれくらい余分になるか分かりません。新しいレコードを検索する前にフルテキストインデックスが再インデックスするのを待つことは、多くの問題の1つになります。

次のようなクエリを作成できます。スペースであなたのsearchstringを分割し、検索タームのリストを作成してください。

 
Select FirstName,MiddleName,LastName 
From person 
WHERE 
Firstname like @searchterm1 + '%' 
or MiddleName like @searchterm1 + '%' 
or LastName like @searchterm1 + '%' 
or Firstname like @searchterm2 + '%' 
etc.... 
2

別のアプローチは、個々のフィールドからの検索を抽象化することです。言い換えれば

が次にビューを検索すなわちFULL_NAME連結フィールドに名姓のようなすべての分割フィールドをオンにしてデータのビューを作成します。これにより、検索クエリがより簡単になる可能性があります。

2

フルテキストの代わりにLucene.netをチェックしてみるとよいでしょう。

関連する問題