Страницы

четверг, 3 июля 2014 г.

Полнотекстовый поиск. Синонимы.

Как известно полнотекстовый поиск позволяет быстро искать строки, в которых встречается определенное слово или комбинация слов. При этом поиск может быть как по точному совпадению, так и по словоформам. Можно также находить предложения, в которых поданные на вход слова находятся на определенном расстоянии друг от друга. Но по умолчанию полнотекстовый поиск не позволяет искать синонимы. То есть, например, мы подаем на вход слово "Привет", а хотим найти строки, в которых есть слово "Привет" или слово "Превед". Для того, чтобы служба полнотекстового поиска справилась с этой задачей необходимо воспользоваться файлами тезауруса. Они находятся в директории MSSQL\FTData инсталляционного каталога экземпляра службы сервера. Доступ к директории есть у  администраторов компьютера. В папке хранятся файлы тезауруса. Такой файл есть для каждого зарегистрированного языка. Для русского языка файл называется tsrus.xml. Итак, для решения поставленной задачи, необходимо открыть файл на изменение и ввести, например, такие данные:
<XML ID="Microsoft Search Thesaurus">
    <thesaurus xmlns="x-schema:tsSchema.xml">
<diacritics_sensitive>0</diacritics_sensitive>
        <replacement>
            <pat>Лодырь</pat>
            <sub>Бездельник</sub>
        </replacement>
<expansion>
            <sub>Привет</sub>
            <sub>Превед</sub>
        </expansion>
<expansion>
            <sub>Владивосток</sub>
            <sub>Влодивосток</sub>
            <sub>Владивостокский</sub>
        </expansion>
    </thesaurus>
</XML>

В этом файле указано, что при поиске синонимов не должны учитываться диакритические знаки (элемент diacritics_sensitive). Также указано, что при вводе в полнотекстовом запросе слова "Привет" надо искать как слово "Привет", так и слово "Превед". При вводе слова "Владивосток", надо искать слова "Владивосток", "Влодивосток", "Владивостокский". Если же вводится слово "Лодырь", то его искать не надо, а вместо него ищется слово "Бездельник".

После того как файл сохранен его надо загрузить на сервер, для этого вызывается хранимая процедура:
exec sp_fulltext_load_thesaurus_file 1049

Данная процедура загружает содержимое файла тезауруса в базу данных tempdb, оно используется полнотекстовыми запросами. Параметр процедуры - это идентификатор языка. Его можно найти, выполнив, например, запрос с каталогу sys.fulltext_languages. Протестируем теперь полнотекстовые запросы. Создадим и наполним таблицу:
create table dbo.Words
(
       iRowId int identity ( 1, 1 )      not null,
       vcWord varchar ( 100 )            not null,
       constraint PK_Words_iRowId primary key clustered ( iRowId asc ) on [PRIMARY]
) on [PRIMARY]

insert into dbo.Words ( vcWord )
       values ( 'Привет' ), ( 'Превед' ), ( 'Владивосток' ), ( 'Владивостока' ), ( 'Влодивосток' ), ( 'Владивостокский' )

Теперь создадим полнотекстовые каталог и индекс:
create fulltext catalog Search
       on filegroup [PRIMARY]
       with accent_sensitivity = off
       authorization dbo

create fulltext index on dbo.Words
       (
             vcWord language russian
       )
       key index PK_Words_iRowId
       on Search
       with stoplist = system, change_tracking = auto

while fulltextcatalogproperty ( N'Search', N'PopulateStatus' ) <> 0
begin
       waitfor delay '00:00:01'
end
exec sp_fulltext_load_thesaurus_file 1049

Выполним следующие полнотекстовые запросы:
select vcWord
from dbo.Words
where freetext ( vcWord, 'Владивосток' )

select vcWord
from dbo.Words
where freetext ( vcWord, 'Привет' )














В резульататах, кроме самого слова, мы видим синонимы и словоформы. Если требуется получить только поданное на вход слово и синонимы, то можно использовать функцию contains с предложением formsof:
select *
from dbo.Words
where contains ( vcWord, 'formsof ( thesaurus, Владивосток )' )








Комментариев нет:

Отправить комментарий