Сравнение полнотекстовых функций и полнотекстовых предикатов

Функции CONTAINSTABLE и FREETEXTTABLE используются для определения полнотекстовых запросов, возвращающих ранжирующие по релевантности значения для каждой строки. Эти функции очень похожи на полнотекстовые предикаты CONTAINS и FREETEXT, но используются по-другому.

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

  • Предикаты CONTAINS и FREETEXT возвращают значения TRUE и FALSE и задаются в предложении WHERE или HAVING инструкции SELECT.
  • Функции CONTAINSTABLE и FREETEXTTABLE возвращают таблицу из нуля, одной или нескольких строк, поэтому они всегда должны определяться в предложении FROM.
  • Предикаты CONTAINS и FREETEXT могут использоваться только для задания критериев выбора, которые Microsoft SQL Server использует для определения членства результирующего набора.
  • Функции CONTAINSTABLE и FREETEXTTABLE также используются для указания критериев выбора. Возвращаемая таблица имеет столбец с именем KEY, который содержит значения полнотекстовых ключей. В каждой зарегистрированной полнотекстовой таблице имеется столбец с гарантированно уникальными значениями. Значения, возвращаемые в ключевом столбце функциями CONTAINSTABLE и FREETEXTTABLE, являются уникальными значениями из полнотекстовой зарегистрированной таблицы для строк, которые соответствуют критериям выбора, заданным в условии полнотекстового поиска.

Более того, в таблице, возвращенной функциями CONTAINSTABLE и FREETEXTTABLE, имеется столбец с именем RANK, содержащий значения от 0 до 1000. Значение прямо пропорционально релевантности. Эти значения используются для ранжирования строк согласно их соответствию критериям выбора.

ms142494.note(ru-ru,SQL.90).gifПримечание.
Значение ранжирования означает только относительный порядок соответствия строк в результирующем наборе. Фактическое значение не столь важно, поэтому не следует ожидать, что он будет одинаковым при каждом запуске запроса. Дополнительные сведения о ранжировании см. в разделе Основные сведения о ранжировании.

Запросы, использующие предикаты CONTAINS и FREETEXT, не возвращают значения ранжирования.

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

Следующий пример возвращает описание и имя категории для всех категорий пищевых продуктов, в которых столбец Description (описание) содержит слова «sweet and savory» рядом со словом «sauces» или словом «candies». Все строки с названием категории «Seafood» (морепродукты) не рассматриваются. Возвращаются только строки ранга 2 и выше.

ms142494.note(ru-ru,SQL.90).gifПримечание.
Чтобы запустить некоторые из этих примеров, нужно установить базу данных Northwind. Сведения об установке базы данных Northwind см. в разделе Загрузка образцов баз данных Northwind и pubs.
USE Northwind;
GO
SELECT FT_TBL.Description, 
   FT_TBL.CategoryName, 
   KEY_TBL.RANK
FROM Categories AS FT_TBL INNER JOIN
   CONTAINSTABLE (Categories, Description, 
      '("sweet and savory" NEAR sauces) OR
      ("sweet and savory" NEAR candies)'
   ) AS KEY_TBL
   ON FT_TBL.CategoryID = KEY_TBL.[KEY]
WHERE KEY_TBL.RANK > 2
   AND FT_TBL.CategoryName <> 'Seafood'
ORDER BY KEY_TBL.RANK DESC;
GO

Сравнение функции CONTAINSTABLE и предиката CONTAINS

Функция CONTAINSTABLE и предикат CONTAINS используют одинаковые условия поиска.

Однако в функции CONTAINSTABLE задается таблица, в которой выполняется полнотекстовый поиск, столбец (или все столбцы) таблицы, в которых выполняется поиск, и условие поиска. Имеется необязательный параметр, который дает пользователю возможность указать, что должно возвращаться только наибольшее заданное количество соответствий. Дополнительные сведения см. в подразделе «Ограничение результирующих наборов» этого раздела.

Функция CONTAINSTABLE возвращает таблицу, включающую в себя столбец с именем RANK. Столбец RANK содержит значение для каждой строки, указывающий степень соответствия этой строки условиям выбора. Чем выше значение ранжирования строки, тем больше ее совпадение с конкретным полнотекстовым запросом.

Сравнение функции FREETEXTTABLE и предиката FREETEXT

Следующий запрос расширяет запрос FREETEXTTABLE таким образом, чтобы он возвратил первыми строки с самыми высокими ранжирующими значениями и добавил ранг каждой строки к списку выбора. Чтобы задать запрос, необходимо знать, что столбец CategoryID является уникальным ключевым столбцом для таблицы Категории.

USE Northwind;
GO
SELECT KEY_TBL.RANK, FT_TBL.Description
FROM Categories AS FT_TBL 
     INNER JOIN
     FREETEXTTABLE(Categories, Description,
                    'How can I make my own beers and ales?') AS KEY_TBL
     ON FT_TBL.CategoryID = KEY_TBL.[KEY]
ORDER BY KEY_TBL.RANK DESC;
GO

Ниже приводится расширение того же запроса, которое возвращает только строки с ранжирующим значением 10 или выше.

USE Northwind;
GO
SELECT KEY_TBL.RANK, FT_TBL.Description
FROM Categories FT_TBL 
     INNER JOIN
     FREETEXTTABLE (Categories, Description,
                    'How can I make my own beers and ales?') AS KEY_TBL
     ON FT_TBL.CategoryID = KEY_TBL.[KEY]
WHERE KEY_TBL.RANK >= 10
ORDER BY KEY_TBL.RANK DESC;
GO

Определение имени уникального ключевого столбца

При создании запросов, которые используют функции для наборов строк, необходимо знать имя уникального ключевого столбца. В каждой таблице с включенным полнотекстовым поиском имеется свойство TableFulltextKeyColumn, содержащее идентификатор столбца, который был выбран для принудительного обеспечения уникальности строк в таблице. В этом примере показано, как получить имя ключевого столбца с помощью программы.

USE AdventureWorks;
GO
DECLARE @key_column sysname
SET @key_column = Col_Name(Object_Id('Production.Document'),
ObjectProperty(Object_id('Production.Document'),
'TableFulltextKeyColumn') 
)
SELECT @key_column AS 'Unique Key Column';
GO

Ограничение результирующих наборов наиболее релевантными результатами

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

ms142494.note(ru-ru,SQL.90).gifПримечание.
При указании аргумента top_n_by_rank возвращается подмножество строк, удовлетворяющее полнотекстовому запросу. Если аргумент top_n_by_rank скомбинирован с другими предикатами, запрос может вернуть меньше строк, чем количество строк, фактически соответствующих всем предикатам.

Имея эти данные, Microsoft SQL Server упорядочивает соответствия по рангу и возвращает только заданное число. Это может привести к значительному повышению производительности. Например, запрос, обычно возвращающий 100 000 строк из таблицы с миллионом строк, обрабатывается гораздо быстрее, если запрошены только 100 строк с самыми высокими ранжирующими значениями.

Если нужно возвратить только 3 строки с самым высоким ранжирующими значениями, запрос с использованием функции CONTAINSTABLE из предыдущего примера будет выглядеть следующим образом.

USE Northwind;
GO
SELECT   K.RANK, CompanyName, ContactName, Address
FROM      Customers AS C
         INNER JOIN
         CONTAINSTABLE(Customers,Address, 'ISABOUT ("des*",
            Rue WEIGHT(0.5),
            Bouchers WEIGHT(0.9))', 3) AS K
         ON C.CustomerID = K.[KEY];
GO

Результирующий набор:

RANK CompanyName          ContactName       address            
---- ------------         -----------       -------            
123  Bon app'             Laurence Lebihan  12, rue des Bouchers 
65   Du monde entier      Janine Labrune    67, rue des Cinquante Otages 
15   France restauration  Carine Schmitt    54, rue Royale     

Этот пример возвращает описание и имя категории для 10 категорий пищевых продуктов с самым высоким значением ранжирования, в которых столбец Description содержит слова «sweet and savory» рядом со словом «sauces» или «candies».

SELECT FT_TBL.Description, 
   FT_TBL.CategoryName, 
   KEY_TBL.RANK
FROM Categories AS FT_TBL INNER JOIN
   CONTAINSTABLE (Categories, Description, 
      '("sweet and savory" NEAR sauces) OR
      ("sweet and savory" NEAR candies)'
      , 10
   ) AS KEY_TBL
   ON FT_TBL.CategoryID = KEY_TBL.[KEY];
GO

См. также

Другие ресурсы

Функция CONTAINSTABLE (Transact-SQL)
FREETEXTTABLE (Transact-SQL)

Справка и поддержка

Получение помощи по SQL Server 2005