全文谓词和全文函数概述

全文查询使用全文谓词(CONTAINS 和 FREETEXT)以及全文函数(CONTAINSTABLE 和 FREETEXTTABLE)。它们支持复杂的 Transact-SQL 语法,这种语法支持各种形式的查询词。若要编写全文查询,必须了解何时以及如何使用这些谓词和函数。本主题总结了这些谓词和函数,并探讨了 CONTAINS 谓词和 CONTAINSTABLE 函数之间的一些共性。

全文谓词(CONTAINS 和 FREETEXT)的概述

CONTAINS 和 FREETEXT 在 SELECT 语句的 WHERE 或 HAVING 子句中指定。它们可以与任何其他 Transact-SQL 谓词(例如 LIKE 和 BETWEEN)结合使用。

CONTAINS 和 FREETEXT 谓词返回 TRUE 或 FALSE 值。它们只能用于指定选择条件,以确定给定的行是否与全文查询相匹配。匹配的行在结果集中返回。

当使用 CONTAINS 或 FREETEXT 时,可以指定搜索表中的单个列、一组列或所有列。此外,还可以指定语言,以便给定的全文查询使用此语言的资源进行断字和词干分析、同义词库查找以及干扰词删除。

CONTAINS 和 FREETEXT 可用于搜索不同种类的匹配项,如下所示:

  • 使用 CONTAINS(或 CONTAINSTABLE)可搜索单个词和短语的精确或模糊(不太精确的)匹配项、在一定差别范围内的相近词或加权匹配项。当使用 CONTAINS 时,必须指定至少一个搜索条件,该搜索条件须指定要搜索的文本以及确定匹配项的条件。

    可以在搜索条件之间使用逻辑运算。有关详细信息,请参阅本主题后面的使用布尔运算符 — AND、OR、AND NOT(在 CONTAINS 和 CONTAINSTABLE 中)。

  • 使用 FREETEXT(或 FREETEXTTABLE)可搜索与指定词、短语或句子(“Freetext 字符串”)的含义相符但措辞不完全相同的匹配项。只要在指定列的全文索引中找到任何搜索词或任何搜索词的任何形式,就会生成匹配项。

若要针对链接服务器执行查询,可以在 CONTAINS 或 FREETEXT 中使用由四部分组成的名称。有关详细信息,请参阅查询链接服务器(全文搜索)

有关这些谓词的语法和参数的信息,请参阅 CONTAINS (Transact-SQL)FREETEXT (Transact-SQL)

注意注意

当数据库兼容级别设为 100 时,不允许在 OUTPUT 子句中使用全文谓词。

示例

A. 将 CONTAINS 用于 <simple_term>

下面的示例将查找包含 "Mountain" 一词且价格为 $80.99 的所有产品。

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

B. 使用 FREETEXT 搜索包含指定字符值的词

下例搜索包含与 vital、safety、components 相关的单词的所有文档。

USE AdventureWorks;
GO
SELECT Title
FROM Production.Document
WHERE FREETEXT (Document, 'vital safety components' );
GO

全文函数(CONTAINSTABLE 和 FREETEXTTABLE)概述

像一般的表名一样,CONTAINSTABLE 和 FREETEXTTABLE 函数也可以在 SELECT 语句的 FROM 子句中进行引用。它们返回与全文查询匹配的、包含零行、一行或多行的表。返回的表只包含与该函数的全文搜索条件中指定的选择条件相匹配的基表的行。

使用这些函数之一的查询返回每一行的相关性排名值 (RANK) 和全文键 (KEY),如下所示:

  • KEY 列

    KEY 列返回所返回行的唯一值。可使用 KEY 列指定选择条件。

  • RANK 列

    RANK 列返回每一行的排名值,此值指示该行与选择条件相匹配的程度。行中文本或文档的排名值越高,该行与给定的全文查询的相关性就越高。请注意,不同行的排名可以相同。可以通过指定可选的 top_n_by_rank 参数限制返回的匹配项的数目。有关详细信息,请参阅对排名的结果集进行限制(全文搜索)搜索查询结果如何进行排名(全文搜索)

当使用这些函数之一时,必须指定要进行全文搜索的基表。与谓词一样,可以指定搜索表中的单个列、一组列或所有列;此外,还可以指定给定的全文查询将使用的资源的语言。

CONTAINSTABLE 用来搜索的匹配项的种类与 CONTAINS 相同,FREETEXTTABLE 用来搜索的匹配项的种类与 FREETEXT 相同。有关详细信息,请参阅本主题前面的全文谓词(CONTAINS 和 FREETEXT)概述。当运行使用 CONTAINSTABLE 和 FREETEXTTABLE 函数的查询时,必须将返回的行与 SQL Server 基表中的行显式联接起来。

有关这些函数的语法和参数的信息,请参阅 CONTAINSTABLE (Transact-SQL)FREETEXTTABLE (Transact-SQL)

示例

A. 使用 CONTAINSTABLE

下面的示例将返回符合以下条件的所有食品类别的说明和类别名称:Description 列中词“sauces”或“candies”附近存在词语“sweet and savory”。将忽略类别名称为“Seafood”的所有行。仅返回排名值为 2 或排名值更高的行。

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

B. 使用 FREETEXTTABLE

下面的示例扩展了 FREETEXTTABLE 查询,以便首先返回排名最高的行,然后将每一行的排名添加到选择列表中。若要指定该查询,必须知道 CategoryIDCategories 表的唯一键列。

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

使用布尔运算符 — AND、OR、AND NOT(在 CONTAINS 和 CONTAINSTABLE 中)

CONTAINS 谓词和 CONTAINSTABLE 函数使用相同的搜索条件。它们都支持使用布尔运算符(AND、OR、AND NOT)将多个搜索词组合起来,以执行逻辑运算。例如,可以使用 AND 查找既包含“latte”又包含“New York-style bagel”的行。例如,可以使用 AND NOT 查找包含“bagel”但不包含“cream cheese”的行。

注意注意

相反,FREETEXT 和 FREETEXTTABLE 将布尔值项视为词来搜索。

有关将 CONTAINS 与其他使用逻辑运算符 AND、OR 和 NOT 的谓词结合使用的信息,请参阅搜索条件 (Transact-SQL)

示例

下例使用 AdventureWorks 数据库的 ProductDescription 表。该查询使用 CONTAINS 谓词搜索 ID 不等于 5 并且既包含词“Aluminum”又包含词“spindle”的说明。该搜索条件使用 AND 布尔运算符。

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

其他注意事项

每个启用全文的表都有一个列,该列用于强制实现表中行的唯一性(“唯一键列”)。当编写 CONTAINSTABLE 或 FREETEXTTABLE 类型的全文查询时,需要使用此唯一键列的名称。有关详细信息,请参阅如何查询全文键列 (Transact-SQL)

许多查询词在很大程度上依赖于断字符行为。为了确保您使用的是正确的断字符(和词干分析器)以及同义词库文件,我们建议您指定 LANGUAGE 参数。有关详细信息,请参阅创建全文索引时选择语言的最佳实践

当定义全文查询时,全文引擎会去除搜索条件中的非索引字(也称为干扰词)。非索引字是可能经常出现但通常对搜索特定文本没有帮助的词,如“a”、“and”、“is”或“the”。非索引字在非索引字表中列出。每个全文索引都与一个特定的非索引字表相关联,该非索引字表决定在进行索引时省略查询或索引中的哪些非索引字。有关详细信息,请参阅非索引字和非索引字表

默认情况下,对于指定 FORMSOF THESAURUS 子句的 CONTAINS 和 CONTAINSTABLE Transact-SQL 查询以及 FREETEXT 和 FREETEXTABLE 查询,会进行同义词库匹配。