Статьи

SQL Server полнотекстового поиска Protips Часть 2: СОДЕРЖИТ против FREETEXT

В первой части этой серии статей мы рассмотрели методологию включения базы данных Sql Server для полнотекстовой индексации и включения полнотекстовых указателей на конкретные таблицы. Но теперь мы подошли к хорошей части — как использовать этот индекс в вашем приложении.

Существует четыре основных функции T-SQL, которые позволяют взаимодействовать с вашими полнотекстовыми индексами: CONTAINS, FREETEXT, CONTAINSTABLE и FREETEXTTABLE. Первые два возвращают логическое значение, означающее, что вы можете использовать их непосредственно в предложении WHERE. Последние два возвращают таблицу из двух столбцов — KEY и RANK, что позволяет управлять поиском по рангу.

Сегодня мы рассмотрим CONTAINS и FREETEXT; CONTAINSTABLE и FREETEXTTABLE будут перечислены позже. В любом случае, важно помнить, что CONTAINS гораздо более конкретен и гораздо более настраиваем, чем FREETEXT. Первые ищут с использованием параметров, о которых говорится, тогда как последние будут разбивать слова, находить инфлекционные формы и выполнять другие магические действия. Очевидно, что FREETEXT является более дорогим из двух, и часто это может быть излишним.

Смущены еще? Как насчет некоторых примеров? Для этого мы будем использовать почтенную базу данных PUBS. (Если у вас нет копии, вы можете загрузить сценарий базы данных от Microsoft .) Он имеет какие-либо настройки полнотекстовых функций, но мы собираемся запустить на нем следующий SQL:

--Enable database for full-text querying exec sp_fulltext_database 'enable' --Create catalog exec sp_fulltext_catalog 'PubsCatalog', 'create' --Enable titles table for fulltext indexing exec sp_fulltext_table 'titles', 'create', 'PubsCatalog', 'UPKCL_titleidind' --Add columns exec sp_fulltext_column 'titles', 'title', 'add' exec sp_fulltext_column 'titles', 'notes', 'add' --start change tracking to force indexing exec sp_fulltext_table 'titles', 'start_change_tracking' 

Вышеуказанное просто устанавливает базу данных для полнотекстовой индексации и включает ее в некоторых столбцах выбора. Полное объяснение настройки полнотекстовой индексации см. В части 1 .

СОДЕРЖИТ против FREETEXT

CONTAINS и FREETEXT — довольно похожие функции. Оба возвращают логическое значение, и оба принимают 2 параметра: имя столбца с произвольным текстом и термин поиска в свободном тексте. Но они ведут себя совсем по-другому. Для наглядного примера выполните следующие запросы:

SELECT title_id, title FROM Titles WHERE CONTAINS(notes, 'recipe') SELECT title_id, title FROM Titles WHERE FREETEXT(notes, 'recipe')
SELECT title_id, title FROM Titles WHERE CONTAINS(notes, 'recipe') SELECT title_id, title FROM Titles WHERE FREETEXT(notes, 'recipe') 

Обратите внимание, что первая инструкция SELECT возвращает ноль строк, а вторая инструкция SELECT возвращает три строки. Почему ты спрашиваешь? Потому что СОДЕРЖИТ специфично. Поле примечаний содержит термин «получатели», но НЕ «получатель». FREETEXT автоматически добавляет в поиск инфлективные формы слова, что приводит к более слабому набору результатов.

Расширение СОДЕРЖИТ

Возможно, вы сейчас говорите: «Да, этот предикат CONTAINS довольно бесполезен». Но это далеко от истины. Существует полный синтаксис запросов в свободном тексте, который позволяет вам выполнять очень плавные поиски, используя CONTAINS. Во-первых, можно намеренно заставить его найти все словоформы, используя FORMSOF. Расширение приведенного выше примера для:

SELECT title_id, title FROM Titles WHERE CONTAINS(notes, 'FORMSOF(INFLECTIONAL, recipe)')
SELECT title_id, title FROM Titles WHERE CONTAINS(notes, 'FORMSOF(INFLECTIONAL, recipe)') 

Возвращаются результаты в трех строках, как в примере FREETEXT. Еще одна полезная техника ищет несколько терминов. Допустим, вы хотели записывать книги о кухне и / или рецептах. Вы можете изменить запрос так:

SELECT title_id, title FROM Titles WHERE CONTAINS(notes, 'FORMSOF(INFLECTIONAL, recipe) or FORMSOF(INFLECTIONAL, cuisine)')
SELECT title_id, title FROM Titles WHERE CONTAINS(notes, 'FORMSOF(INFLECTIONAL, recipe) or FORMSOF(INFLECTIONAL, cuisine)') 

Этот запрос должен вернуть четыре строки, добавив книгу с кухней в список результатов запроса.

Приведенные выше примеры едва касаются поверхности — можно очень, очень увлекаться поисковыми предложениями CONTAINS , чтобы получить конкретные и индивидуальные наборы результатов поиска. Разработчик может указать вес каждого поискового запроса, чтобы получить более конкретные результаты. Или попросить слова РЯДОМ друг с другом. С надлежащим парсером вы можете получить некоторые очень конкретные результаты из довольно открытого окна поиска. Тем не менее, есть один важный элемент, который СОДЕРЖИТ и FREETEXT не хватает для создания этих результатов: своего рода внешнее ранжирование значения результатов поиска. Введите две полнотекстовые функции TABLE — CONTAINSTABLE и FREETEXTTABLE. Для получения дополнительной информации об использовании этих функций T-SQL следите за обновлениями в части 3 этой серии.