Полнотекстовый поиск в MS SQL Express и его использование с LINQ to SQL

31.10.2009 0:17 / Артём Волк / 5358 просмотров / ...

Для включения функции полнотекстового поиска в MS SQL редакции Express (проверялось на 2005-й версии) нужно немного больше действий, чем для использования полнотекстовых индексов в MyISAM-таблицах MySQL, но всё возможно.

В качестве примера будет использоваться реализация полнотекстового поиска в БД этого сайта.

Первое, что нужно сделать — поставить версию MS SQL Server Express with Advanced Services, не забыв при установке выбрать компонент FullText Search.

Проверка доступных языков

Выполнив этот запрос, можно убедиться, что родной поддержки русского языка нет. Это не мешает работать полнотекстовому поиску, но поддержки словоформ не будет. Для решения есть несколько workaround'ов, предусматривающих ручную установку нужных модулей.

SELECT * FROM [sys].[fulltext_languages]

Создание каталога

Каталог — место хранения индексов:

CREATE FULLTEXT CATALOG [SnippetsCatalog]

Проверить наличие созданного каталога можно командой:

SELECT * FROM [sys].[fulltext_catalogs]

Создание полнотекстового индекса

Создаём индекс для таблицы с автоматическим отслеживанием изменений:

CREATE FULLTEXT INDEX ON [Snippets] (
	[Title]  
		Language 0, 
	[Text]
		Language 0
)
KEY INDEX [PK_Snippets]
ON [SnippetsCatalog]
WITH CHANGE_TRACKING AUTO

Проверяем, что индекс создался

SELECT * FROM [sys].[fulltext_indexes]

Использование индекса

Для удобства создаём функцию, возвращающую табличное значение, которую можно будет использовать в LINQ-запросах:

CREATE FUNCTION [dbo].[fn_GetSnippetsByFullText]
(
	@search_string varchar(250),
	@search_count int
)
RETURNS TABLE
AS
RETURN 
(
	SELECT TOP (@search_count) [Snippets].* FROM 
	FREETEXTTABLE([Snippets],([Title],[Text]), @search_string) AS [SEARCH_RESULT]
	LEFT JOIN [Snippets] ON [Snippets].[Id] = [SEARCH_RESULT].[KEY]
	ORDER BY [SEARCH_RESULT].[RANK] DESC	
)

Проверяем, что всё работает:

SELECT * FROM fn_GetSnippetsByFullText('ASP.NET', 20)

LINQ to SQL

Перетянув хранимую функцию в визуальном дизайнере классов LINQ (важно не забыть указать тип возвращаемого результата) её можно использовать в C#-коде:

var result = from s in Db.GetSnippetsByFullText('PHP', 20) select s;