CONTAINS (Transact-SQL)

Предикат, используемый в предложении WHERE для поиска столбцов, содержащих символьные типы данных, и проверки точного или нечеткого (менее точного) совпадения с отдельными словами и фразами, расстояния между словами или взвешенных совпадений.

В SQL Server в полнотекстовых предикатах CONTAINS или FREETEXT при выполнении запросов к связанным серверам можно использовать четырехкомпонентные имена.

CONTAINS может производить поиск:

  • слова или фразы;

  • префикса слова или фразы;

  • слова около другого слова;

  • слова, флективно сформированного из другого (например, слово «drive» является флективной основой слов «drives», «drove», «driving» и «driven»);

  • слова, которое является синонимом другого слова, с использованием тезауруса (например, слово «metal» может иметь синоним «aluminum» и «steel»).

Значок ссылки на разделСинтаксические обозначения в Transact-SQL

Синтаксис

CONTAINS
      ( { column_name | ( column_list ) | * } 
          , '<contains_search_condition>'     
   [ , LANGUAGE language_term ]
      ) 

<contains_search_condition> ::= 
    { <simple_term> 
    | <prefix_term> 
    | <generation_term> 
    | <proximity_term> 
    | <weighted_term> 
    } 
    | { ( <contains_search_condition> ) 
    [ { <AND> | <AND NOT> | <OR> } ] 
    <contains_search_condition> [ ...n ] 
    } 

<simple_term> ::= 
          word | "phrase"

<prefix term> ::= 
     { "word *" | "phrase *" }

<generation_term> ::= 
     FORMSOF ( { INFLECTIONAL | THESAURUS } , <simple_term> [ ,...n ] ) 

<proximity_term> ::= 
     { <simple_term> | <prefix_term> } 
     { { NEAR | ~ }
     { <simple_term> | <prefix_term> } 
     } [ ...n ] 

<weighted_term> ::= 
     ISABOUT 
        ( { { 
  <simple_term> 
  | <prefix_term> 
  | <generation_term> 
  | <proximity_term> 
  } 
   [ WEIGHT ( weight_value ) ] 
   } [ ,...n ] 
        ) 

<AND> ::= 
     { AND | & }

<AND NOT> ::= 
     { AND NOT | &! }

<OR> ::= 
     { OR | | }

Аргументы

  • column_name
    Имя столбца с полнотекстовым индексом в таблице, указанной в предложении FROM. Столбцы могут иметь тип char, varchar, nchar, nvarchar, text, ntext, image, xml, varbinary или varbinary(max).

  • column_list
    Задает несколько столбцов, разделенных запятыми. Параметр column_list необходимо заключать в скобки. Если не определен аргумент language_term, то язык для всех столбцов column_list должен быть одинаковым.

  • *
    Указывает, что запрос выполняет поиск по заданному условию во всех столбцах таблицы, указанной в предложении FROM, для которых существуют полнотекстовые индексы. Столбцы в предложении CONTAINS должны принадлежать одной таблице, для которой существует полнотекстовый индекс. Если не определен аргумент language_term, то язык для всех столбцов таблицы должен быть одинаковым.

  • LANGUAGE language_term
    Язык, используемый для разбиения по словам, морфологического поиска, расширения и замены тезауруса, а также для удаления пропускаемых слов (или стоп-слов) в ходе запроса. Этот параметр является необязательным.

    Если в одном столбце хранятся документы на различных языках в виде больших двоичных объектов, то код языка заданного документа определяет, какой язык должен использоваться для индексирования его содержимого. Указание параметра LANGUAGE language_term при запросе к такому столбцу может повысить вероятность хорошего соответствия.

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

    Если параметр language_term задан как строка, то он соответствует значению столбца alias в представлении совместимости sys.syslanguages (Transact-SQL). Строка должна быть заключена в одиночные кавычки: 'language_term'. Если значением аргумента language_term является целое число, оно представляет собой действительный код языка. Если значение language_term задано в шестнадцатеричной форме, то после символов «0x» должна следовать шестнадцатеричная запись кода языка. Шестнадцатеричное значение не может иметь более восьми знаков, включая начальные нули.

    Если значение указано в двухбайтовой кодировке (DBCS), SQL Server преобразует его в Юникод.

    Если указанный язык является недопустимым или связанные с ним ресурсы не установлены, то SQL Server возвращает сообщение об ошибке. Для использования нейтральных языковых ресурсов следует указать 0x0 в качестве значения аргумента language_term.

  • <contains_search_condition>
    Текст, который необходимо найти в столбце column_name, и условия соответствия.

    Аргумент <contains_search_condition> имеет тип nvarchar. Если в качестве входных данных используется другой тип символьных данных, производится неявное преобразование. В следующем примере переменная @SearchWord, тип которой определен как varchar(30), вызывает неявное преобразование в предикате CONTAINS.

    USE AdventureWorks2008R2;
    GO
    DECLARE @SearchWord varchar(30)
    SET @SearchWord ='performance'
    SELECT Description 
    FROM Production.ProductDescription 
    WHERE CONTAINS(Description, @SearchWord);
    

    Так как пробное сохранение параметров не работает с преобразованием, для улучшения производительности следует использовать тип nvarchar. В данном примере следует объявить переменную @SearchWord с типом nvarchar(30).

    USE AdventureWorks2008R2;
    GO
    DECLARE @SearchWord nvarchar(30)
    SET @SearchWord = N'performance'
    SELECT Description 
    FROM Production.ProductDescription 
    WHERE CONTAINS(Description, @SearchWord);
    

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

  • word
    Строка символов без пробелов и знаков препинания.

  • phrase
    Одно или несколько слов с пробелами между ними.

    ПримечаниеПримечание

    Существуют языки (например, используемые в некоторых странах Азии), которые могут содержать фразы, состоящие из одного или нескольких слов без пробелов между ними.

  • <simple_term>
    Указывает соответствие для точного слова или фразы. Примерами допустимых простых выражений являются "база данных", данные и "Microsoft SQL Server". Фразы должны заключаться в двойные кавычки (""). Слова во фразе должны стоять в таком же порядке, как задано в аргументе <contains_search_condition>, по мере их появления в столбце базы данных. Поиск символов в слове или фразе проводится без учета регистра. Пропускаемые слова (или стоп-слова, такие как «a», «and» или «the»), содержащиеся в столбцах полнотекстового индекса, не хранятся в полнотекстовом индексе. Если при поиске по одному слову используется слово из числа пропускаемых, SQL Server возвращает сообщение об ошибке, указывая на то, что запрос содержит только пропускаемые слова. SQL Server включает стандартный список пропускаемых слов в каталоге \Mssql\Binn\FTERef каждого экземпляра SQL Server.

    Знаки препинания пропускаются. Поэтому предикат CONTAINS(testing, "computer failure") соответствует строке «Where is my computer? Failure to find it would be expensive». Дополнительные сведения о поведении модулей разбиения на слова см. в разделе Средства разбиения по словам и парадигматические модули.

  • <prefix_term>
    Указывает совпадение слов или фраз, начинающихся с указанного текста. Префиксные выражения должны заключаться в двойные кавычки (""); необходимо добавлять звездочку (*) перед закрывающей кавычкой, чтобы совпадал весь текст, начинающийся с простого выражения, заданного до звездочки. Предложение должно быть задано таким образом: CONTAINS (column, '"text*"'). Звездочка заменяет ноль, один или более символов (корневого слова или слов в слове или фразе). Если текст и звездочка не заключены в двойные кавычки и предикат выглядит как CONTAINS (column, 'text*'), то полнотекстовый поиск считает звездочку символом и ищет точное совпадение с text*. Полнотекстовое ядро не найдет слов со звездочкой (*), т. к. средства разбиения по словам обычно пропускают такие символы.

    Если параметр <prefix_term> является фразой, то каждое содержащееся во фразе слово считается отдельным префиксом. Этому запросу, задающему префиксное выражение «local wine*», отвечают все строки с текстом «local winery», «locally wined and dined» и т. д.

  • <generation_term>
    Задает совпадение слов, если включенные простые выражения содержат варианты начального искомого слова.

  • INFLECTIONAL
    Задает языковой парадигматический модуль, который будет использован для заданного простого выражения. Поведение парадигматического модуля определено правилами формирования основ для каждого конкретного языка. У нейтрального языка нет связанного с ним парадигматического модуля. Язык столбцов, к которым выполняется запрос, используется для обращения к необходимому парадигматическому модулю. Если указан аргумент language_term, используется парадигматический модуль, соответствующий этому языку.

    Заданный аргумент <simple_term> в пределах <generation_term> не будет соответствовать одновременно существительным и глаголам.

  • THESAURUS
    Указывает, что используется тезаурус, соответствующий языку полнотекстового столбца или языку, заданному в запросе. Самый длинный шаблон или шаблоны аргумента <simple_term> сравниваются с тезаурусом, и создаются дополнительные условия, которые можно использовать для расширения или замены начального шаблона. Если совпадений не найдено для всего аргумента <simple_term> или для его части, несовпадающая часть обрабатывается как simple_term. Дополнительные сведения о тезаурусе полнотекстового поиска см. в разделе Конфигурация тезауруса.

  • <proximity_term>
    Указывает совпадение слов или фраз, которые должны находиться в документе, где выполняется поиск. Аналогично оператору AND параметр <proximity_term> требует наличия обоих терминов поиска в документе.

    • NEAR | ~
      Показывает, что для получения соответствия необходимо, чтобы в документе встречались слово или фраза, указанные с каждой стороны оператора NEAR или ~. Несколько выражений с учетом расположения можно объединять в цепочки, например a NEAR b NEAR c или a ~ b ~ c. Для получения соответствия необходимо, чтобы все выражения с учетом расположения, входящие в цепочку, находились в документе.

      Если выражение поиска по сходству используется в функции CONTAINSTABLE, то оно влияет на ранг каждого документа. Чем ближе искомые выражения находятся в документе, тем выше будет ранг документа. Если между искомыми выражениями находится > 50 других выражений, для документа возвращается ранг 0.

      Например, конструкции CONTAINS (column_name, 'лиса NEAR курица') и CONTAINSTABLE (table_name, column_name, 'лиса ~ курица') возвратят все документы, в указанном столбце которых содержатся и слово «лиса», и слово «курица». Кроме того, функция CONTAINSTABLE возвращает для каждого документа ранг, основанный на схожести слов «лиса» и «курица». Например, если документ содержит фразу «лиса съела курицу», то ранг будет высоким.

      Оператор NEAR указывает логическое расстояние между выражениями, а не абсолютное расстояние. Например, выражения, находящиеся в различных фразах и выражениях в пределах абзаца, считаются более удаленными друг от друга, чем фразы, находящиеся в одной фразе или в одном предложении, независимо от фактического расстояния между ними, поскольку предполагается, что в первом случае выражения в меньшей степени связаны. Аналогично выражения из различных абзацев считаются еще более удаленными друг от друга.

  • <weighted_term>
    Указывает на то, что совпадающие строки (возвращенные запросом) соответствуют списку слов и фраз, каждому из которых при необходимости дано взвешенное значение.

  • ISABOUT
    Указывает ключевое слово <weighted_term>.

    • WEIGHT(weight_value)
      Указывает взвешенное значение, которое может принимать значение от 0,0 до 1,0. Каждый компонент в аргументе <weighted_term> может включать аргумент weight_value, который является способом изменения того, как различные части запроса влияют на значение ранга, назначенное каждой строке, удовлетворяющей условию запроса. Параметр WEIGHT не влияет на результаты запросов CONTAINS, но влияет на ранг в запросах CONTAINSTABLE.

      ПримечаниеПримечание

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

  • { AND | & } | { AND NOT | &! } | { OR | | }
    Задает логическую операцию между двумя условиями поиска на вхождение.

    • AND | &
      Указывает на то, что для совпадения оба условия поиска на вхождение должны быть удовлетворены. Символ амперсанда (&) может быть использован вместо ключевого слова AND для представления оператора AND.

    • AND NOT | &!
      Указывает на то, что для совпадения второе условие поиска на вхождение не должно быть удовлетворено. Символ амперсанда с последующим восклицательным знаком (&!) может быть использован вместо ключевого слова AND NOT для представления оператора AND NOT.

    • OR | |
      Указывает на то, что для совпадения любое из условий поиска на вхождение должно быть удовлетворено. Символ черты (|) может быть использован вместо ключевого слова OR для представления оператора OR.

      Если аргумент <contains_search_condition> содержит группы, заключенные в круглые скобки, эти группы вычисляются в первую очередь. После вычисления групп, заключенных в скобки, эти правила применяются при использовании следующих логических операторов с условиями поиска на вхождение.

      • NOT применяется перед AND.

      • NOT может стоять только после AND, как в AND NOT. Оператор OR NOT недопустим. NOT не может быть указано перед первым условием. Например, условие CONTAINS (mycolumn, 'NOT "phrase_to_search_for" ' ) недопустимо.

      • AND применяется перед OR.

      • Логические операторы одного типа (AND, OR) являются ассоциативными, и поэтому они могут быть применены в любом порядке.

      • n
        Заполнитель, указывающий, что могут быть заданы несколько условий поиска CONTAINS и входящих в них выражений.

Замечания

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

CONTAINS не распознается как ключевое слово, если уровень совместимости меньше 70. Дополнительные сведения см. в разделе sp_dbcmptlevel (Transact-SQL).

Полнотекстовые предикаты не допускаются в предложении OUTPUT, если уровень совместимости базы данных установлен в значение 100.

В отличие от полнотекстового поиска предикат LIKETransact-SQL работает только на комбинациях символов. Кроме того, предикат LIKE нельзя использовать в запросах к форматированным двоичным данным. Более того, запрос с предикатом LIKE к большому количеству неструктурированных текстовых данных выполняется гораздо медленнее, чем эквивалентный полнотекстовый запрос к тем же данным. Выполнение запроса LIKE к миллионам строк текстовых данных может занять несколько минут, в то время как полнотекстовый запрос к тем же данным занимает всего несколько секунд или даже меньше (в зависимости от количества возвращаемых строк).

Примеры

A. Использование CONTAINS с <simple_term>

В следующем примере выполняется поиск всех продуктов с ценой $80.99, которые содержат слово "Mountain".

USE AdventureWorks2008R2;
GO
SELECT Name, ListPrice
FROM Production.Product
WHERE ListPrice = 80.99
   AND CONTAINS(Name, 'Mountain');
GO

Б. Использование CONTAINS и фразы в <simple_term>

В следующем примере возвращаются все товары, которые содержат фразу "Mountain" или "Road".

USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' "Mountain" OR "Road" ')
GO

В. Использование CONTAINS с <prefix_term>

Следующий пример возвращает все имена товаров, содержащие по крайней мере одно слово, начинающееся с префикса «chain» в столбце Name.

USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' "Chain*" ');
GO

Г. Использование CONTAINS и OR с <prefix_term>

В следующем примере возвращаются все описания категорий, которые содержат строки с префиксами "chain" или "full".

USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, '"chain*" OR "full*"');
GO

Д. Использование CONTAINS с <proximity_term>

В следующем примере возвращаются все названия продуктов, которые содержат слово bike около слова performance.

USE AdventureWorks2008R2;
GO
SELECT Description
FROM Production.ProductDescription
WHERE CONTAINS(Description, 'bike NEAR performance');
GO

Е. Использование CONTAINS с <generation_term>

В следующем примере выполняется поиск всех товаров с формами слова ride: «riding», «ridden» и т. д.

USE AdventureWorks2008R2;
GO
SELECT Description
FROM Production.ProductDescription
WHERE CONTAINS(Description, ' FORMSOF (INFLECTIONAL, ride) ');
GO

Ж. Использование CONTAINS с <weighted_term>

В следующем примере выполняется поиск всех названий продуктов, содержащих слова performance, comfortable или smooth, при этом для каждого слова задается определенный вес.

USE AdventureWorks2008R2;
GO
SELECT Description
FROM Production.ProductDescription
WHERE CONTAINS(Description, 'ISABOUT (performance weight (.8), 
comfortable weight (.4), smooth weight (.2) )' );
GO

З. Использование CONTAINS с переменными

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

USE AdventureWorks2008R2;
GO
DECLARE @SearchWord nvarchar(30)
SET @SearchWord = N'Performance'
SELECT Description 
FROM Production.ProductDescription 
WHERE CONTAINS(Description, @SearchWord);
GO

И. Использование CONTAINS с логическим оператором (AND)

В следующем примере используется таблица ProductDescription базы данных База данных AdventureWorks2008R2. Запрос использует предикат CONTAINS для поиска описаний, в которых идентификатор описания не равен 5 и описание содержат слова «Aluminum» и «spindle». Условие поиска использует логический оператор AND.

USE AdventureWorks2008R2;
GO
SELECT Description
FROM Production.ProductDescription
WHERE ProductDescriptionID <> 5 AND
   CONTAINS(Description, ' Aluminum AND spindle');
GO

К. Использование CONTAINS для проверки вставки строки

В следующем примере предикат CONTAINS используется во вложенном запросе SELECT. Используя базу данных База данных AdventureWorks2008R2, запрос получает значение комментария из всех комментариев в таблице ProductReview для конкретного велосипеда. Условие поиска использует логический оператор AND.

USE AdventureWorks2008R2;
GO
INSERT INTO Production.ProductReview 
(ProductID, ReviewerName, EmailAddress, Rating, Comments) 
VALUES
(780, 'John Smith', 'john@fourthcoffee.com', 5, 
'The Mountain-200 Silver from Adventure Works Cycles meets and exceeds expectations. I enjoyed the smooth ride down the roads of Redmond')
 
-- Given the full-text catalog for these tables is Adv_ft_ctlg, 
-- with change_tracking on so that the full-text indexes are updated automatically.
WAITFOR DELAY '00:00:30'   
-- Wait 30 seconds to make sure that the full-text index gets updated.
 
SELECT r.Comments, p.Name
FROM Production.ProductReview r
JOIN Production.Product p 
ON
 r.ProductID = p.ProductID
 
AND r.ProductID = (SELECT ProductID
                  FROM Production.ProductReview
                  WHERE CONTAINS (Comments, 
                                 ' Adventure Works AND 
                                   Redmond AND 
                                   "Mountain-200 Silver" '))

GO

См. также

Задания

Справочник

Основные понятия