2013-03-04 3 views
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.

+0

Есть ли связь между этими двумя таблицами? –

ответ

6

Предполагая, что существует связь между субъектом и ответами вы можете создать вид WITH SCHEMABINDING, создать UNIQUE CLUSTERED индекс на представлении, а затем добавить эту точку зрения в свой каталог полнотекстового выбрав два столбца, которые вы хотите включить.

0

Когда возникают огромные запросы параллельного запроса, СУБД не могут позволить себе это SQL. Более того, выбор SQL поддерживает полнотекстовый поиск. Поэтому вам нужна библиотека IR (Information Retrieval), такая как Lucene для java.

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, Тип) и, наконец, ваш полнотекстовый индекс.

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; 
0

Я видел, что NopCommerce (C# MVC Open Source E-Commerce) сделал с помощью полнотекстового поиска по 'продуктов' и 'варианты' и возвращать только 'продукты'. Это очень похоже на ваш случай, потому что вы хотите искать в «Thread» и «Replies», но вы, очевидно, хотите только вернуть «потоки». У меня есть изменить его, чтобы использовать темы и ответы для вас:

Во-первых, создать функцию, которая генерирует индексное название таблицы (по желанию):

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 ([email protected]_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) 

Затем, в хранимой процедуре получения продуктов по ключевым словам, создать временную таблицу со списком идентификаторов продуктов, которые соответствуют ключевым словам.

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 присоединиться к списку нитей и вернуть их.

Надеюсь, это поможет.

Смежные вопросы