FREETEXTTABLE: примеры (SQL)

Использование FREETEXTTABLE для лингвистического поиска в SQL Server
Раздел: Весовые функции полнотекстового поиска, Полнотекстовый поиск
FREETEXTTABLE(table, column [, 'freetext_string' [, LANGUAGE language_term]]): table

Описание функции FREETEXTTABLE

FREETEXTTABLE является функцией полнотекстового поиска в Microsoft SQL Server, которая возвращает таблицу строк, релевантных заданному текстовому запросу. Ее применяют для сложного поиска по смыслу, а не точному совпадению. Функция анализирует запрос, выделяет ключевые слова и ищет их синонимы или формы слов, используя лингвистический анализ. Функция возвращает табличное значение, которое можно присоединить к исходной таблице.

Аргументы функции:

  • table - имя таблицы, в которой выполняется поиск.
  • column - имя столбца или список столбцов, разделенных запятыми, в которых осуществляется поиск.
  • freetext_string - текст для поиска. SQL Server разбивает его на отдельные слова, определяет их значимость и ищет соответствия.
  • top_n_by_rank - необязательный целочисленный параметр. Указывает, сколько строк с наивысшим рангом возвращать.
  • language_code - необязательный параметр, указывающий язык для лингвистического анализа запроса и данных.
  • search_property_list - необязательный параметр, указывающий на список свойств поиска, если поиск ведется по свойствам.

Возвращаемое значение: таблица с двумя столбцами: KEY (уникальный ключ строки исходной таблицы) и RANK (целочисленное значение от 0 до 1000, указывающее релевантность).

Краткие примеры использования

Пример 1: Базовый вызов функции.

SELECT *
FROM FREETEXTTABLE(Products, ProductDescription, 'надежный и долговечный компьютер') AS ft
ORDER BY RANK DESC;
KEY      RANK
------ ----
1025 245
1048 187

Пример 2: Использование параметра top_n_by_rank.

SELECT *
FROM FREETEXTTABLE(Products, ProductDescription, 'тихий вентилятор', 5) AS ft;
KEY      RANK
------ ----
2012 456
2015 321
2018 210

Пример 3: Указание языка для поиска.

SELECT *
FROM FREETEXTTABLE(Articles, Content, 'успешное выполнение проекта', 10, 0x0419) AS ft;
KEY      RANK
------ ----
55 789
67 654

Похожие функции MS SQL

В MS SQL Server для полнотекстового поиска применяют несколько функций.

  • CONTAINSTABLE: Осуществляет более точный поиск с поддержкой операторов близости, взвешивания терминов и грамматических форм. Используют, когда нужен детальный контроль над условиями поиска.
  • FREETEXT: Возвращает логическое значение (TRUE/FALSE) для строки. Ее удобно применять в условии WHERE для фильтрации строк, а не получения ранга.
  • CONTAINS: Аналогична CONTAINSTABLE, но возвращает логическое значение. Подходит для точного поиска с комплексными условиями в WHERE.

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

Аналоги в других системах

MySQL: Используют оператор MATCH ... AGAINST в режиме естественного языка (IN NATURAL LANGUAGE MODE).

SELECT id, description,
MATCH (description) AGAINST ('надежный компьютер' IN NATURAL LANGUAGE MODE) AS relevance
FROM products
WHERE MATCH (description) AGAINST ('надежный компьютер' IN NATURAL LANGUAGE MODE);
id  description          relevance
1 Надежный ПК 1.5
3 Компьютер для офиса 0.8

PostgreSQL: Применяют типы tsvector и tsquery с операторами @@ и ts_rank.

SELECT id, title,
ts_rank(to_tsvector('russian', content), plainto_tsquery('russian', 'успешный проект')) AS rank
FROM articles
WHERE to_tsvector('russian', content) @@ plainto_tsquery('russian', 'успешный проект')
ORDER BY rank DESC;
id  title               rank
2 Отчет о проекте 0.123

Oracle: Функция CONTAINS в составе Oracle Text. Возвращает оценку релевантности (SCORE).

SELECT id, score(1) AS relevance
FROM documents
WHERE CONTAINS(text_column, 'проект успешный', 1) > 0
ORDER BY score(1) DESC;
ID  RELEVANCE
10 85

Основное отличие MS SQL FREETEXTTABLE - встроенная лингвистическая обработка для русского языка и возврат результата в виде таблицы, готовой для JOIN.

Распространенные ошибки

Ошибка 1: Вызов функции для таблицы, на которой не активирован полнотекстовый поиск.

SELECT * FROM FREETEXTTABLE(MyTable, Description, 'текст');
Сообщение об ошибке: 'Full-Text Search is not installed, or a full-text component cannot be loaded.'

Ошибка 2: Указание несуществующего столбца или столбца без полнотекстового индекса.

SELECT * FROM FREETEXTTABLE(Products, ProductName, 'слово');
Сообщение об ошибке: 'Cannot use a CONTAINS or FREETEXT predicate on table 'Products' because it is not full-text indexed.'

Ошибка 3: Неправильное соединение результата FREETEXTTABLE с основной таблицей из-за несоответствия типа ключа.

SELECT p.*
FROM Products p
INNER JOIN FREETEXTTABLE(Products, Description, 'компьютер') ft ON p.ID = ft.[KEY];
-- Если тип столбца p.ID - varchar, а ft.[KEY] - int, возникнет ошибка.

Изменения в новых версиях

В SQL Server 2012 и более поздних версиях появилась поддержка свойства search_property_list для поиска по структурированным свойствам документа. В SQL Server 2017 и 2019 улучшена интеграция с другими компонентами, но базовый синтаксис и поведение функции остались стабильными. Для использования новейших возможностей, таких как семантический поиск, требуется отдельная настройка.

Расширенные сценарии применения

Пример 1: Поиск по нескольким столбцам с присоединением исходной таблицы.

Пример sql
SELECT p.ProductID, p.ProductName, p.ListPrice, ft.RANK
FROM Production.Product AS p
INNER JOIN FREETEXTTABLE(Production.Product, (Name, Color), 'серебристый велосипед') AS ft
ON p.ProductID = ft.[KEY]
WHERE p.ListPrice > 1000
ORDER BY ft.RANK DESC;
ProductID  ProductName            ListPrice  RANK
---------- -------------------- --------- ----
777 Горный велосипед 1500.00 245
888 Шоссейный велосипед 1200.00 198

Пример 2: Комбинирование результатов FREETEXTTABLE и CONTAINSTABLE с помощью UNION.

Пример sql
SELECT 'FREETEXT' AS Source, ft.[KEY], ft.RANK
FROM FREETEXTTABLE(Documents, Content, 'финансовый отчет') AS ft
UNION ALL
SELECT 'CONTAINS' AS Source, ct.[KEY], ct.RANK
FROM CONTAINSTABLE(Documents, Content, 'ISABOUT (финансовый WEIGHT(0.8), отчет WEIGHT(0.4))') AS ct
ORDER BY RANK DESC;
Source    KEY     RANK
------- --- ----
CONTAINS 102 856
FREETEXT 102 345
FREETEXT 105 210

Пример 3: Использование параметра language_code для многоязычных данных.

Пример sql
-- Поиск с указанием английского языка (0x0409)
SELECT *
FROM FREETEXTTABLE(Books, Summary, 'successful business strategy', 0, 0x0409) AS ft_en
UNION
-- Поиск с указанием русского языка (0x0419)
SELECT *
FROM FREETEXTTABLE(Books, Summary, 'успешная бизнес стратегия', 0, 0x0419) AS ft_ru;

MS SQL FREETEXTTABLE function comments

En
FREETEXTTABLE Returns a table of zero or more rows for columns containing meaning-based matches