Полнотекстовый поиск в MS SQL Express и его использование с LINQ to SQL
Для включения функции полнотекстового поиска в 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;
