4

フォーラム アプリケーションでは、スレッドの実際の名前がテーブルに格納され、返信が別のテーブルに格納されます。

Table_Thread 
 Subject varchar(255) e.g. "How to setup fulltext search"

Table_Replies (users replies here)
  ReplyText text(not null)

ここで、件名列と返信列の両方で全文検索を作成したいと考えていますが、これらは非常に関連しているように見えるため、同じインデックスにある必要があります。

これを行うことは可能ですか?

SQL Server 2005 を使用しています。

4

4 に答える 4

6

件名と返信の間に関連付けがあると仮定すると、ビューWITH SCHEMABINDINGを作成し、ビューにインデックスを作成しUNIQUE CLUSTEREDてから、含める 2 つの列を選択してそのビューをフルテキスト カタログに追加できます。

于 2013-03-06T22:57:39.377 に答える
0

両方のインデックス付き列とテーブルのPKの和集合を含むインデックス付きビューを作成できます

例えば

CREATE VIEW SearchText
WITH SCHEMABINDING
AS SELECT * FROM (
(Subject as Text, Table_Thread_ID as ID, 1 as Type FROM Table_Thread)
UNION ALL
(ReplyText as Text, Table_Replies_ID as ID, 2 as Type FROM Table_Replies));

フルテキストインデックスを作成するには一意のキーが必要なので、タイプ1と2を任意に配置します。次に、(ID、Type)に一意のインデックスを作成し、最後にフルテキストインデックスを作成します。

CREATE UNIQUE INDEX SearchText_UK ON SearchText (ID, Type);
CREATE FULLTEXT CATALOG ft AS DEFAULT;
CREATE FULLTEXT INDEX ON SearchText(Text) 
   KEY INDEX SearchText_UK 
   WITH STOPLIST = SYSTEM;
于 2013-03-13T14:58:31.093 に答える
0

NopCommerce (C# MVC オープン ソース E コマース) が「製品」と「バリアント」の全文検索を使用して行ったことを見てきましたが、「製品」のみが返されます。「スレッド」と「返信」を検索したいが、明らかに「スレッド」のみを返したいため、これはあなたのケースと非常に似ています。スレッドと返信を使用するように変更しました。

まず、テーブルごとにインデックス名を生成する関数を作成します (オプション)。

CREATE FUNCTION [dbo].[nop_getprimarykey_indexname]
(
    @table_name nvarchar(1000) = null
)
RETURNS nvarchar(1000)
AS
BEGIN
    DECLARE @index_name nvarchar(1000)

    SELECT @index_name = i.name
    FROM sys.tables AS tbl
    INNER JOIN sys.indexes AS i ON (i.index_id > 0 and i.is_hypothetical = 0) AND (i.object_id=tbl.object_id)
    WHERE (i.is_unique=1 and i.is_disabled=0) and (tbl.name=@table_name)

    RETURN @index_name
END
GO

次に、カタログとインデックスを作成してフルテキストを有効にします。

EXEC('
IF NOT EXISTS (SELECT 1 FROM sys.fulltext_catalogs WHERE [name] = ''myFullTextCatalog'')
    CREATE FULLTEXT CATALOG [myFullTextCatalog] AS DEFAULT')


DECLARE @create_index_text nvarchar(4000)
SET @create_index_text = '
IF NOT EXISTS (SELECT 1 FROM sys.fulltext_indexes WHERE object_id = object_id(''[Table_Thread]''))
    CREATE FULLTEXT INDEX ON [Table_Thread]([Subject])
    KEY INDEX [' + dbo.[nop_getprimarykey_indexname] ('Table_Thread') +  '] ON [myFullTextCatalog] WITH CHANGE_TRACKING AUTO'
EXEC(@create_index_text)

SET @create_index_text = '
IF NOT EXISTS (SELECT 1 FROM sys.fulltext_indexes WHERE object_id = object_id(''[Table_Replies]''))
    CREATE FULLTEXT INDEX ON [Table_Replies]([ReplyText])
    KEY INDEX [' + dbo.[nop_getprimarykey_indexname] ('Table_Replies') +  '] ON [myFullTextCatalog] WITH CHANGE_TRACKING AUTO'
EXEC(@create_index_text)

次に、キーワードで製品を取得するためのストアド プロシージャで、キーワードに一致する製品 ID のリストを含む一時テーブルを作成します。

    INSERT INTO #KeywordThreads ([ThreadId])
    SELECT t.Id
    FROM Table_Thread t with (NOLOCK)
    WHERE CONTAINS(t.[Subject], @Keywords)

    UNION
    SELECT r.ThreadId
    FROM Table_Replies r with (NOLOCK)
    WHERE CONTAINS(pv.[ReplyText], @Keywords)

これで、一時テーブル#KeywordThreadsを使用してスレッドのリストと結合し、それらを返すことができます。

これが役立つことを願っています。

于 2013-03-13T16:43:40.110 に答える
0

大量の同時クエリ要求が来ると、RDBMS は SQL では対応できません。さらに、select SQL は全文検索をうまくサポートしていません。そのため、Lucene for java などの IR (Information Retrieval) ライブラリが必要です。

于 2013-03-13T03:11:43.923 に答える