среда, 8 августа 2012 г.

Основы полнотекстового поиска MS SQL Server 2008 (Full-Text Search)


Не буду описывать, что такое полнотекстовый индекс, хотя немного можно цитатой из BOL:

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

Для работы полнотекстового поиска  необходимо, чтобы работала служба MSSQLFDLauncher (fdhost.exe), которая необходима для фильтрации, разбиения по словам данных из таблиц.

В отличие, от MS SQL 2005, задачи которые выполнялись службой  MSFTESQL , теперь выполняются процессом  sql server.

Создание полнотекстового индекса выполняется по следующим шагам:
      1.       Создание полнотекстового каталога

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

3.       Заполнение полнотекстового индекса

1. Итак, создадим полнотекстовый каталог:

Его можно создать либо из графического интерфейса(БД->Storage ->Full Text Catalogs), либо командой t-sql:

CREATE FULLTEXT CATALOG [test_catalog]WITH ACCENT_SENSITIVITY = ON

AS DEFAULT

AUTHORIZATION [dbo]

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

CREATE FULLTEXT INDEX ON [Production].[ProductDescription]

(Description language 1033)KEY INDEX [AK_ProductDescription_rowguid] ON ([test_catalog])

 WITH (CHANGE_TRACKING MANUAL)

GO

Где Description language 1033 язык данных ключа уникального индексе AK_ProductDescription_rowguid , который будет проиндексирован. Список поддерживаемых языков для полнотекстового индексирования можно получить из представления  sys.fulltext_languages.

CHANGE_TRACKING MANUALустанавливаем, что обновление индекса будет

Индекс создан, сами полнотекстовые индексы модно получить из представления  sys.fulltext_indexes.

3. После этого можно наш индекс заполнять данными.

При создание индекса, индекс заполняется автоматически, так же при создание мы указываем тип обновления индекса, в примере:

WITH (CHANGE_TRACKING MANUAL) – обновление вручную

Еще варианты AUTO и OFF.

Рекомендуется запускать настраивать индекс с параметром “Manual”, но если таблица, на которую настроен полнотекстовый индекс, обновляется мало, можно и “AUTO”. Дело в том , что обновление полнотекстового индекса происходит немного по другому, в отличие от кластерных \не кластерных индексов.

Заполнение индекса  новыми данными или обновление информации , выполняется командой:

alter  fulltext index on Production.ProductDescription START FULL POPULATION

Запросы с полнотекстовым индексом:

Самый простой способ – это использование  freetext и CONTAINS

select * from Production.ProductDescription

where freetext(Description,'bike')

go

select * from Production.ProductDescription

where CONTAINS (Description,'bike')

Разница, что например для второго запроса не выдадут результаты со словом , например,  bikes”.

Еще одно замечание, по умолчанию при создание индекса, если явно не указано, индекс сопоставляется с системным стоп-листом “system”, п о этому стоп-листу не будут находиться , например, числовые значение(раз, два и т.д.)

Указать стоп лист можно либо при создание полнотекстового индекса, либо если уже индекс командой:

alter  fulltext index on Production.ProductDescription set  stoplist=test_stlist
Еще несколько примеров по запросам к полнотекстовым каталогам:
есть таблица со следующими данными:
id val
1 раз
2 Раз
3 Раз два
4 Раз, два
5 Разовый, два
6 Разовый, двоичный
7 тРи
8 раз два три четеры
9 Раз, два, три, четыре
10 Раз, два, три, четыре, пять
11 Первый второй третий
12 стоп
13 стоп два раза
14 стоппп
15 стоп - стоять
16 стоп снова
17 два, раз, ноль
18 два, раз
19 два, ноль, раз

1-й  запрос к данной таблице:
SELECT
[id],[val]
FROM [test_db].[dbo].[tbl_rusful]

where CONTAINS(val,'Раз')
Результат:
id val
1 раз
2 Раз
3 Раз два
4 Раз, два
8 раз два три четеры
9 Раз, два, три, четыре
10 Раз, два, три, четыре, пять
17 два, раз, ноль
18 два, раз
19 два, ноль, раз

2-ой запрос:
SELECT [id],[val]

FROM [test_db].[dbo].[tbl_rusful]

where CONTAINS(val,'"Раз" and "Два"')
Результат:
id val
3 Раз два
4 Раз, два
8 раз два три четеры
9 Раз, два, три, четыре
10 Раз, два, три, четыре, пять
17 два, раз, ноль
18 два, раз
19 два, ноль, раз

3 -й запрос:
SELECT [id],[val]

FROM [test_db].[dbo].[tbl_rusful]

where CONTAINS(val,'"Раз*" near "Два"')
Результат:
id val
3 Раз два
4 Раз, два
5 Разовый, два
8 раз два три четеры
9 Раз, два, три, четыре
10 Раз, два, три, четыре, пять
13 стоп два раза
17 два, раз, ноль
18 два, раз
19 два, ноль, раз


По базовым параметрам службы полнотекстового поиска пока все.

1 комментарий :

  1. Здравствуйте, уважаемый коллега. Не подскажете, как бы сделать:
    передаю фразу. Ищется она сначала целиком. Если ничего не найдено тогда она уже делится на слова и они ищутся. Если последний вариант в принципе ясен, это
    select * from Production.ProductDescription
    where freetext(Description,'bike' and 'USA'), то для первого ничего кроме like 'This is super bike from the USA' не приходит в голову

    ОтветитьУдалить