FREETEXTTABLE: примеры (SQL)
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: Поиск по нескольким столбцам с присоединением исходной таблицы.
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.
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 для многоязычных данных.
-- Поиск с указанием английского языка (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;