使用 Full-Text 搜索进行查询

若要定义全文搜索,SQL Server 全文查询使用全文谓词(CONTAINS 和 FREETEXT)和函数(CONTAINSTABLE 和 FREETEXTTABLE)。 这些语法支持丰富的 Transact-SQL 语法,这些语法支持各种形式的查询词。 若要编写全文查询,必须了解何时以及如何使用这些谓词和函数。

Full-Text 谓词(CONTAINS 和 FREETEXT)的概述

CONTAINS 和 FREETEXT 谓词返回 TRUE 或 FALSE 值。 它们只能用于指定选择条件,以确定给定行是否与全文查询匹配。 结果集中返回匹配行。 CONTAINS 和 FREETEXT 是在 SELECT 语句的 WHERE 或 HAVING 子句中指定的。 它们可与任何其他 Transact-SQL 谓词(如 LIKE 和 BETWEEN)组合在一起。

注释

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

使用 CONTAINS 或 FREETEXT 时,可以指定要搜索的表中的单个列、列列表或所有列。 (可选)您可以指定用于给定全文查询的语言资源,这些资源将用于断字和词干分析、同义词库查找及干扰词去除。

CONTAINS 和 FREETEXT 可用于不同类型的匹配,如下所示:

  • 使用 CONTAINS(或 CONTAINSTABLE)来进行精确匹配或模糊匹配(较不精确),适用于单个词和短语、特定距离内词汇的邻近关系或加权匹配。 使用 CONTAINS 时,必须指定至少一个搜索条件,该条件指定要搜索的文本以及确定匹配项的条件。

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

  • 使用 FREETEXT(或 FREETEXTTABLE)来匹配指定单词、短语或句子( 自由文本字符串)的含义,但不是确切的措辞。 如果在指定列的全文索引中找到任何术语或任何术语的形式,则会生成匹配项。

可以使用 CONTAINS 或 FREETEXT 谓词中的四部分名称查询链接服务器上的目标表的全文索引列。 若要准备远程服务器以接收全文查询,请在远程服务器上的目标表和列上创建全文索引,然后将该远程服务器添加为链接服务器。

注释

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

例子

答: 将 CONTAINS 与<simple_term>配合使用

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

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

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

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

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

Full-Text 函数概述(CONTAINSTABLE 和 FREETEXTTABLE)

CONTAINSTABLE 和 FREETEXTTABLE 函数在 SELECT 语句的 FROM 子句中被引用时,像常规表名称一样使用。 它们返回与全文查询匹配的零行、一行或多行的表。 返回的表仅包含与函数全文搜索条件中指定的选定条件匹配的基表的行。

注释

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

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

  • KEY 列

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

  • 排名列

    RANK 列返回每一行的 排名值 ,该值指示行与选择条件的匹配程度。 行中文本或文档的排名值越高,该行对于给定的全文查询越相关。 请注意,不同的行可以按相同方式进行排名。 可以通过指定可选的 top_n_by_rank 参数来限制要返回的匹配项数。 有关详细信息,请参阅 “使用 RANK 限制搜索结果”。

使用其中任一函数时,必须指定要搜索全文的基表。 与谓词一样,可以指定要搜索的表中的单个列、列列表或所有列,并且可以选择指定要由给定全文查询使用其资源的语言。

CONTAINSTABLE 对于与 CONTAINS 相同的匹配类型非常有用,而 FREETEXTTABLE 对于与 FREETEXT 相同的匹配类型非常有用。 有关详细信息,请参阅本主题前面的 Full-Text 谓词(CONTAINS 和 FREETEXT)概述。 在运行使用 CONTAINSTABLE 和 FREETEXTTABLE 函数的查询时,必须将返回的行与 SQL Server 基表中的行显式联接。

通常,CONTAINSTABLE 或 FREETEXTTABLE 的结果需要与基表联接。 在这种情况下,需要知道唯一键列名称。 用于确保表中行的唯一性,这是每个启用全文搜索功能的表中都有的列(唯一**键列)。 有关详细信息,请参阅 “管理 Full-Text 索引”。

例子

答: 使用 CONTAINSTABLE

以下示例返回说明列中包含单词“铝”,且邻近词语为“光”或“轻便”的所有产品的说明ID和说明。仅返回排名值为2或更高的行。

USE AdventureWorks2012  
GO  
  
SELECT FT_TBL.ProductDescriptionID,  
   FT_TBL.Description,   
   KEY_TBL.RANK  
FROM Production.ProductDescription AS FT_TBL INNER JOIN  
   CONTAINSTABLE (Production.ProductDescription,  
      Description,   
      '(light NEAR aluminum) OR  
      (lightweight NEAR aluminum)'  
   ) AS KEY_TBL  
   ON FT_TBL.ProductDescriptionID = KEY_TBL.[KEY]  
WHERE KEY_TBL.RANK > 2  
ORDER BY KEY_TBL.RANK DESC;  
GO  

B. 使用 FREETEXTTABLE

以下示例扩展 FREETEXTTABLE 查询以先返回排名最高的行,并将每行的排名添加到选择列表中。 若要指定查询,必须知道 ProductDescriptionID 是表的唯一键列 ProductDescription

USE AdventureWorks2012  
GO  
  
SELECT KEY_TBL.RANK, FT_TBL.Description  
FROM Production.ProductDescription AS FT_TBL   
     INNER JOIN  
     FREETEXTTABLE(Production.ProductDescription, Description,  
                    'perfect all-around bike') AS KEY_TBL  
     ON FT_TBL.ProductDescriptionID = KEY_TBL.[KEY]  
ORDER BY KEY_TBL.RANK DESC  
GO  

下面是仅返回排名值为 10 或更高值的行的同一查询的扩展:

USE AdventureWorks2012  
GO  
  
SELECT KEY_TBL.RANK, FT_TBL.Description  
FROM Production.ProductDescription AS FT_TBL   
     INNER JOIN  
     FREETEXTTABLE(Production.ProductDescription, Description,  
                    'perfect all-around bike') AS KEY_TBL  
     ON FT_TBL.ProductDescriptionID = KEY_TBL.[KEY]  
WHERE KEY_TBL.RANK >= 10  
ORDER BY KEY_TBL.RANK DESC  
GO  

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

CONTAINS 谓词和 CONTAINSTABLE 函数使用相同的搜索条件。 这两者都支持使用布尔运算符-AND、OR、AND NOT-执行逻辑作来组合多个搜索词。 例如,可以使用 AND 查找同时包含“拿铁”和“纽约风格的百吉饼”的行。 例如,可以使用 AND NOT 查找包含“bagel”但不包含“奶油奶酪”的行。

注释

相比之下,FREETEXT 和 FREETEXTTABLE 将布尔词视为要搜索的字词。

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

示例:

以下示例使用 AdventureWorks2012 数据库的 ProductDescription 表。 查询使用 CONTAINS 谓词来搜索说明,其中说明 ID 不等于 5,说明中同时包含字词“铝”和“主轴”。搜索条件使用 AND 布尔运算符。

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

有关 Full-Text 查询的其他注意事项

编写全文查询时,还要考虑以下事项:

  • LANGUAGE选项

    许多查询词在很大程度上依赖于分词器的工作方式。 为了确保您使用正确的分词器、词干分析器和同义词库文件,我们建议您指定 LANGUAGE 选项。 有关详细信息,请参阅 创建 Full-Text 索引时选择语言

  • 非索引字

    定义全文查询时,Full-Text 引擎会放弃搜索条件中的非索引字(也称为干扰词)。 停用词是诸如“a”、“and”、“is”或“the”这样的词,这些词经常出现,但在搜索特定文本时通常没有帮助。 停用词被列在停用词列表中。 每个全文索引都与一个特定的停用词列表相关联,该列表决定在索引时哪些停用词会被从查询或索引中省略。 有关详细信息,请参阅 为全文搜索配置和管理非索引字和非索引字表

  • 同义词库

    默认情况下,FREETEXT 和 FREETEXTTABLE 查询使用同义词库。 CONTAINS 和 CONTAINSTABLE 支持可选的 THESAURUS 参数。

  • 事例敏感性

    全文搜索查询不区分大小写。 然而,在日语中,有多个拼音正交字,其中正交规范化的概念类似于不区分大小写(例如,kana = 不敏感)。 不支持这种类型的正字法规范化。

查询 varbinary(max) 和 xml 列

如果为 varbinary(max)varbinaryxml 列编制全文索引,则可以使用全文谓词(CONTAINS 和 FREETEXT)和函数(CONTAINSTABLE 和 FREETEXTTABLE)查询它,就像任何其他全文索引列一样。

重要

全文搜索也适用于图像列。 但是,将在 image SQL Server 的未来版本中删除该数据类型。 避免在新开发工作中使用此数据类型,并计划修改当前使用它的应用程序。 请改用 varbinary(max) 数据类型。

varbinary(max) 或 varbinary 数据

单个 varbinary(max) 列或 varbinary 列可以存储多种类型的文档。 SQL Server 支持在操作系统中已安装筛选器并可用的任何文档类型。 每个文档的文档类型由文档的文件扩展名标识。 例如,对于.doc文件扩展名,全文搜索使用支持Microsoft Word 文档的筛选器。 有关可用文档类型的列表,请查询 sys.fulltext_document_types 目录视图。

请注意,Full-Text 引擎可以利用操作系统中已安装的现有筛选器。 在使用操作系统筛选器、断字器和词干提取器之前,必须在服务器实例中加载它们,具体步骤如下操作:

EXEC sp_fulltext_service @action='load_os_resources', @value=1  

若要在 varbinary(max) 列上创建全文索引,Full-Text 引擎需要访问位于 varbinary(max) 列的文档的文件扩展名。 此信息必须存储在表列(称为类型列)中,该列必须与全文索引中的列相关联 varbinary(max) 。 为文档编制索引时,Full-Text 引擎使用类型列中的文件扩展名来标识要使用的筛选器。

xml 数据

xml数据类型列仅存储 XML 文档和片段,并且仅对文档使用 XML 筛选器。 因此,不需要类型列。 xml 列上的全文索引为 XML 元素的内容编制索引,但忽略 XML 标记。 属性值是全文索引的,除非它们是数值。 元素标记用作标记边界。 支持格式正确的 XML 或 HTML 文档和包含多种语言的片段。

有关查询 xml 列的详细信息,请参阅 “对 XML 列使用 Full-Text 搜索”。

支持的查询词形式

本部分汇总了全文谓词和行集值函数为每种形式的查询提供的支持。

注释

对于给定查询词的语法,请单击下表的“ 支持 ”列中的相应链接。

查询术语表单 DESCRIPTION 支持的服务
一个或多个特定字词或短语(简单术语 在全文搜索中,单词(或 标记)是一个字符串,其边界由相应的断字符标识,遵循指定语言的语言规则。 有效短语由多个单词组成,它们之间带有或不带任何标点符号。

例如,“可颂”是一个单词,“咖啡厅”也是。 au lait“是一个短语。 此类字词和短语称为简单术语。

有关详细信息,请参阅本主题后面的 “搜索特定字词”或“短语”(简单术语)。
CONTAINSCONTAINSTABLE 查找短语的完全匹配项。

FREETEXTFREETEXTTABLE 将短语分解为单独的单词。
单词或短语,其中单词以指定文本开头(前缀词 前缀词是指一个字符串,该字符串附加到单词的前面,以生成派生词或偏转形式。

对于单个前缀词,以指定术语开头的任何单词都将是结果集的一部分。 例如,术语“auto*”与“automatic”、“automobile”等匹配。

对于短语,短语中的每个单词都被视为前缀词。 例如,术语“auto tran*”可以匹配“自动变速器”和“汽车传感装置”,但不能匹配“自动电机变速器”。

有关详细信息,请参阅本主题后面的 “执行前缀搜索”(前缀术语)。
CONTAINSCONTAINSTABLE
特定词的屈折形式(词形变化 屈折形式是动词的不同时态和变位形式,以及名词的单数和复数形式。 例如,搜索单词“drive”的词形变化形式。 如果表中的各个行包含单词“drive”、“drives”、“drove”、“driving”和“driven”,则所有行都将位于结果集中,因为这些单词都是从词根“drive”通过词形变化生成的。

有关详细信息,请参阅本主题后面的 “搜索特定单词(生成术语)的转折形式”。
默认情况下,FREETEXTFREETEXTTABLE 查找所有指定词语的词形变化形式。

CONTAINSCONTAINSTABLE 支持可选的 INFLECTIONAL 参数。
特定单词的同义词形式(生成术语同义词库 同义词库为术语定义用户指定的同义词。 例如,如果将条目“{car,automobile, truck, van}”添加到同义词库,则可以搜索单词“car”的同义词库形式。 表中查询的所有行(包括单词“automobile”、“truck”、“van”或“car”)都出现在结果集中,因为这些单词都属于包含单词“car”的同义词扩展集。

有关同义词库文件结构的信息,请参阅 配置和管理用于 Full-Text 搜索的同义词库文件
默认情况下,FREETEXTFREETEXTTABLE 使用同义词库。

CONTAINSCONTAINSTABLE 支持可选的 THESAURUS 参数。
与另一单词或短语接近的单词或短语(邻近词 邻近词表示彼此接近的字词或短语。还可以指定分隔第一个和最后一个搜索词的最大非搜索词数。 此外,还可以按任意顺序或指定字词或短语的顺序搜索字词或短语。

例如,你想要查找“ice”这个单词接近“冰球”这个单词或“滑冰”这个短语接近“冰球”这个短语的行。

有关详细信息,请参阅 使用 NEAR 搜索靠近另一个单词的字词
CONTAINSCONTAINSTABLE
使用加权值的字词或短语(加权词 一个加权值,该值指示一组字词和短语中每个单词和短语的重要性程度。 权重值为 0.0 是最低的,权重值为 1.0 是最高的。

例如,在搜索多个词的查询中,可以为每个搜索词分配一个权重值,该值指示其重要性相对于搜索条件中的其他单词。 根据分配给搜索词的相对权重,这种类型的查询的结果首先返回最相关的行。 结果集包含包含任何指定术语的文档或行(或它们之间的内容);但是,由于与不同的搜索词关联的加权值的变化,某些结果将被视为比其他结果更相关。

有关详细信息,请参阅本主题后面的“使用加权值(加权术语)搜索字词或短语”。
CONTAINSTABLE

搜索特定字词或短语(简单术语)

可以使用 CONTAINSCONTAINSTABLEFREETEXTFREETEXTTABLE 来在表中搜索特定短语。 例如,如果您要在 AdventureWorks2012 数据库中的 ProductReview 表中搜索,查找所有关于包含短语“learning curve”的产品的评论,可以使用 CONTAINS 谓词,如下所示:

USE AdventureWorks2012  
GO  
  
SELECT Comments  
FROM Production.ProductReview  
WHERE CONTAINS(Comments, '"learning curve"')  
GO  

搜索条件(在本例中为“学习曲线”)可能相当复杂,可以由一个或多个字词组成

执行前缀搜索(前缀词汇)

可以使用 CONTAINSCONTAINSTABLE 搜索具有指定前缀的字词或短语。 返回列中包含以指定前缀开头的文本的所有条目。 例如,搜索包含前缀top的所有行,例如top``pletop``pingtop。 查询如下所示:

USE AdventureWorks2012  
GO  
  
SELECT Description, ProductDescriptionID  
FROM Production.ProductDescription  
WHERE CONTAINS (Description, '"top*"' )  
GO  

返回与星号 \ 之前指定的文本匹配的所有文本。 如果文本和星号不是用双引号分隔的,如中 CONTAINS (DESCRIPTION, 'top*')所示,全文搜索不会将星号视为通配符。

当前缀词是一个短语时,组成该短语的每个标记都被视为单独的前缀词。 将返回所有包含以任何前缀词开头的单词的行。 例如,前缀词“light bread*”将查找包含文本“light breaded”、“lightly breaded”或“light bread”的行,但不会返回“浅烤面包”。

搜索特定单词的词形变化(生成词语)

可以使用 CONTAINSCONTAINSTABLEFREETEXTFREETEXTTABLE 搜索动词的所有不同时态和变位,或者同时搜索名词的单数和复数形式(屈折搜索),或特定单词的同义词形式(同义词搜索)。

以下示例在数据库中表AdventureWorks的列中ProductReview搜索任何形式的“foot”(“foot”、“foot”等Comments)。

USE AdventureWorks2012  
GO  
  
SELECT Comments, ReviewerName  
FROM Production.ProductReview  
WHERE CONTAINS (Comments, 'FORMSOF(INFLECTIONAL, "foot")')  
GO  

注释

全文搜索使用词干分析器,让你能够搜索动词的不同时态和变位,也可以同时搜索名词的单数和复数形式。 有关词干分析器的详细信息,请参阅 配置和管理用于搜索的断字符和词干分析器

通过使用权重值来搜索词语或短语(权重词)

可以使用 CONTAINSTABLE 搜索字词或短语并指定加权值。 以 0.0 到 1.0 之间的数字度量的权重指示一组字词和短语中每个单词和短语的重要性。 权重为 0.0 是最低的,权重为 1.0 是最高的。

以下示例展示了一个查询,该查询通过使用权重搜索所有客户地址,其中任何以字符串“Bay”开头的文本都包含“Street”或“View”。 结果为那些包含指定了更多字词的行提供更高的排名。

USE AdventureWorks2012  
GO  
  
SELECT AddressLine1, KEY_TBL.RANK   
FROM Person.Address AS Address INNER JOIN  
CONTAINSTABLE(Person.Address, AddressLine1, 'ISABOUT ("Bay*",   
         Street WEIGHT(0.9),   
         View WEIGHT(0.1)  
         ) ' ) AS KEY_TBL  
ON Address.AddressID = KEY_TBL.[KEY]  
ORDER BY KEY_TBL.RANK DESC  
GO  

加权术语可与任何简单术语、前缀术语、生成术语或邻近词结合使用。

查看词分割工具、同义词库和停用词表组合的标记化结果

将给定断字符、同义词库和非索引字表组合应用于查询字符串输入后,可以使用 sys.dm_fts_parser 动态管理视图查看标记化结果。 有关详细信息,请参阅sys.dm_fts_parser(Transact-SQL)。

另请参阅

CONTAINS (Transact-SQL)
CONTAINSTABLE (Transact-SQL)
FREETEXT (Transact-SQL)
FREETEXTTABLE (Transact-SQL)
创建 Full-Text 搜索查询(Visual Database Tools)
提高 Full-Text 查询的性能