13

SQL バックエンドを使用して C#/ASP.NET アプリを構築しています。締め切りが迫っており、ページを完成させようとしています。左側のフィールドから、デザイナーの 1 人が私のページの 1 つに全文検索を組み込みました。この時点までの私の「検索」はフィルターであり、特定の要因と列の値によって結果セットを絞り込むことができました。

私は締め切りに近づいているので(猫が食べて吐いたもののように見える時点で、夜は3時間睡眠です)、私はこのページが他のページと非常に似ていることを期待していました。悪臭を放つかどうかを決定します。これまでにページで全文検索を行ったことはありません.... これは登るべき山ですか、それとも簡単な解決策はありますか?

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

4

5 に答える 5

29

まず、本番サーバーで全文検索のインデックス作成を有効にする必要があります。そのため、範囲内にない場合は、これを使用したくないでしょう。

ただし、それがすでに準備ができている場合は、全文検索は比較的簡単です。

T-SQLには、全文検索に使用される4つの述語があります。

  • フリーテキスト
  • フリーテキストテーブル
  • 含む
  • 含む

FREETEXTは最も単純で、次のように実行できます。

SELECT UserName
FROM Tbl_Users
WHERE FREETEXT (UserName, 'bob' )

Results:

JimBob
Little Bobby Tables

FREETEXTTABLEは、結果をテーブルとして返すことを除いて、FreeTEXTと同じように機能します。

T-SQLの全文検索の真の力は、CONTAINS(およびCONTAINSTABLE)述語から得られます...これは巨大なので、その使用法を次の場所に貼り付けます。

CONTAINS
    ( { column | * } , '< contains_search_condition >' 
    ) 

< contains_search_condition > ::= 
        { < simple_term > 
        | < prefix_term > 
        | < generation_term > 
        | < proximity_term > 
        | < weighted_term > 
        } 
        | { ( < contains_search_condition > ) 
        { AND | AND NOT | OR } < contains_search_condition > [ ...n ] 
        } 

< simple_term > ::= 
    word | " phrase "

< prefix term > ::= 
    { "word * " | "phrase * " }

< generation_term > ::= 
    FORMSOF ( INFLECTIONAL , < simple_term > [ ,...n ] ) 

< proximity_term > ::= 
    { < simple_term > | < prefix_term > } 
    { { NEAR | ~ } { < simple_term > | < prefix_term > } } [ ...n ] 

< weighted_term > ::= 
    ISABOUT 
        ( { { 
                < simple_term > 
                | < prefix_term > 
                | < generation_term > 
                | < proximity_term > 
                } 
            [ WEIGHT ( weight_value ) ] 
            } [ ,...n ] 
        ) 

これは、次のようなクエリを記述できることを意味します。

SELECT UserName
FROM Tbl_Users
WHERE CONTAINS(UserName, '"little*" NEAR tables')

Results:

Little Bobby Tables

幸運を :)

于 2008-10-14T19:20:27.610 に答える
2

私は以前、ファイルやデータベースに全文検索を追加するためにdtSearchを使用しましたが、それらはかなり安価で使いやすいものです。

これらすべてを追加してSQLを構成する以外に、このスクリプトはデータベース内のすべての列を検索し、探している値が含まれている列を示します。私はそれが「適切な」解決策ではないことを知っていますが、いつかあなたを買うかもしれません。

/*This script will find any text value in the database*/
/*Output will be directed to the Messages window. Don't forget to look there!!!*/

SET NOCOUNT ON
DECLARE @valuetosearchfor varchar(128), @objectOwner varchar(64)
SET @valuetosearchfor = '%staff%' --should be formatted as a like search 
SET @objectOwner = 'dbo'

DECLARE @potentialcolumns TABLE (id int IDENTITY, sql varchar(4000))

INSERT INTO @potentialcolumns (sql)
SELECT 
    ('if exists (select 1 from [' +
    [tabs].[table_schema] + '].[' +
    [tabs].[table_name] + 
    '] (NOLOCK) where [' + 
    [cols].[column_name] + 
    '] like ''' + @valuetosearchfor + ''' ) print ''SELECT * FROM [' +
    [tabs].[table_schema] + '].[' +
    [tabs].[table_name] + 
    '] (NOLOCK) WHERE [' + 
    [cols].[column_name] + 
    '] LIKE ''''' + @valuetosearchfor + '''''' +
    '''') as 'sql'
FROM information_schema.columns cols
    INNER JOIN information_schema.tables tabs
        ON cols.TABLE_CATALOG = tabs.TABLE_CATALOG
            AND cols.TABLE_SCHEMA = tabs.TABLE_SCHEMA
            AND cols.TABLE_NAME = tabs.TABLE_NAME
WHERE cols.data_type IN ('char', 'varchar', 'nvchar', 'nvarchar','text','ntext')
    AND tabs.table_schema = @objectOwner
    AND tabs.TABLE_TYPE = 'BASE TABLE'
ORDER BY tabs.table_catalog, tabs.table_name, cols.ordinal_position

DECLARE @count int
SET @count = (SELECT MAX(id) FROM @potentialcolumns)
PRINT 'Found ' + CAST(@count as varchar) + ' potential columns.'
PRINT 'Beginning scan...'
PRINT ''
PRINT 'These columns contain the values being searched for...'
PRINT ''
DECLARE @iterator int, @sql varchar(4000)
SET @iterator = 1
WHILE @iterator <= (SELECT Max(id) FROM @potentialcolumns)
BEGIN
    SET @sql = (SELECT [sql] FROM @potentialcolumns where [id] = @iterator)
    IF (@sql IS NOT NULL) and (RTRIM(LTRIM(@sql)) <> '')
    BEGIN
        --SELECT @sql --use when checking sql output
        EXEC (@sql)
    END
    SET @iterator = @iterator + 1
END

PRINT ''
PRINT 'Scan completed'
于 2008-10-14T19:25:18.083 に答える
2

SQL Server での全文検索は非常に簡単です。少し設定を行い、クエリ側を微調整するだけで準備完了です。私はプロセスに精通しているので、20分以内にクライアントのためにそれを行いました

ここに2008 年の MSDN 記事があります。リンクはそこから 2005 バージョンに移動します

于 2008-10-14T19:18:14.323 に答える
1

そこに行ったことがある。スケーラビリティと、それぞれに異なる重み値を指定して複数の列を検索するなどの高度な検索機能を検討し始めるまでは、魅力のように機能します。

たとえば、タイトル列と概要SearchColumn = CONCAT(Title, Summary)列を検索する唯一の方法は、を使用してインデックスを作成する計算列を作成することSearchColumnです。重み付け?SearchColumn = CONCAT(CONCAT(Title,Title), Summary)そんな感じ。;)フィルタリング?気にしないで。

于 2008-10-14T20:13:39.140 に答える
0

「どれくらい難しいか」というのは、答えるのが難しい質問です。たとえば、すでに 10 回やった人はおそらく簡単だと思います。私が本当に言えることは、自分で作成するよりもNLuceneのようなものを使用した方が、はるかに簡単になる可能性が高いということです。

于 2008-10-14T19:17:03.357 に答える