使用全文搜索进行查询

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例

使用谓词 CONTAINSFREETEXT 以及行集值函数 CONTAINSTABLEFREETEXTTABLE,并结合 SELECT 语句编写全文查询。 本文提供每个谓词和函数的示例,并帮助用户选择要使用的最佳谓词和函数。

  • 要匹配单词和短语,可使用 CONTAINS 和 CONTAINSTABLE
  • 若要匹配含义,而不是完全匹配原文措辞,请使用 FREETEXTFREETEXTTABLE

每个谓词和函数的示例

以下示例使用 AdventureWorks 示例数据库。 有关 AdventureWorks 的最终版本,请参阅 AdventureWorks 示例数据库。 要运行示例查询,还需要设置全文搜索。 有关详细信息,请参阅全文搜索入门

示例 - CONTAINS

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

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

示例 - FREETEXT

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

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

示例 - CONTAINSTABLE

以下示例返回所有产品的说明 ID 和说明,这些产品的 Description 列包含单词“aluminum”,且该单词邻近“light”或“lightweight”。仅返回排名为 2 或更高的行。

USE AdventureWorks2022  
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  

示例 - FREETEXTTABLE

以下示例扩展了 FREETEXTTABLE 查询,以便首先返回排名最高的行,然后将每一行的排名添加到选择列表中。 要编写类似查询,必须知道 ProductDescriptionID 是 ProductDescription 表的唯一键列

USE AdventureWorks2022  
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 AdventureWorks2022  
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 / CONTAINSTABLEFREETEXT/FREETEXTTABLE 可用于不同类型的匹配。 以下信息有助于为查询选择最佳的谓词或函数:

CONTAINS/CONTAINSTABLE

  • 使用精确或模糊(不太精确)匹配来匹配单个单词和短语。
  • 也可以执行以下操作:
    • 指定单词彼此之间在一定距离内的相对位置关系。
    • 返回加权匹配项。
    • 使用逻辑运算来组合搜索条件。 有关详细信息,请参阅本文稍后的使用布尔运算符(AND、OR 和 NOT)

FREETEXT/FREETEXTTABLE

  • 匹配指定单词、短语或句子(Freetext 字符串)的含义,但无法匹配确切的措辞。
  • 只要在指定列的全文索引中找到任何搜索词或任何搜索词的任何形式,就会生成匹配项。

比较谓词和函数

谓词 CONTAINS/FREETEXT 和行集值函数 CONTAINSTABLE/FREETEXTTABLE 具有不同的语法和选项。 以下信息有助于为查询选择最佳的谓词或函数:

谓词 CONTAINS 和 FREETEXT

使用情况。 在 SELECT 语句的 WHERE 或 HAVING 子句中使用全文谓词 CONTAINS 和 FREETEXT。

结果。 CONTAINS 和 FREETEXT 谓词返回 TRUE 或 FALSE 值,指示给定的行是否与全文查询匹配。 匹配的行在结果集中返回。

其他选项。 可将这些谓词与 LIKE 和 BETWEEN 等其他任何 Transact-SQL 谓词结合使用。

可以指定要搜索的表中的单个列、一组列或所有列。

您也可以指定全文查询用于分词和词干分析、同义词库查找以及噪声词删除的语言资源。

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

详细信息。 有关这些谓词的语法和参数的详细信息,请参阅 CONTAINSFREETEXT

行集值函数 CONTAINSTABLE 和 FREETEXTTABLE

使用情况。 在 SELECT 语句的 FROM 子句中使用全文函数 CONTAINSTABLE 和 FREETEXTTABLE,就像使用普通的表名一样。

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

通常,必须将 CONTAINSTABLE 或 FREETEXTTABLE 的结果与基表联接。 要联接这些表,必须知道唯一键列的名称。 该列存在于每个启用了全文检索的表中,用于确保表中的每一行都是唯一的(唯一键列)。 有关键列的更多信息,请参阅创建和管理全文索引

结果。 这些函数返回与全文查询匹配的、包含零行、一行或多行的表。 返回的表只包含与该函数的全文搜索条件中指定的选择条件相匹配的基表的行。

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

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

详细信息。 有关这些函数的语法和参数的详细信息,请参阅 CONTAINSTABLEFREETEXTTABLE

特定搜索类型

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

可以使用 CONTAINSCONTAINSTABLEFREETEXTFREETEXTTABLE 在表中搜索特定单词或短语。 例如,如果要在 AdventureWorks2025 数据库中搜索 ProductReview 表,以查找关于某个产品且包含“学习曲线”这一短语的所有评论,可以使用 CONTAINS 谓词,如下所示:

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

搜索条件(在本例中为“learning curve”)可以很复杂,也可以由一个或多个词组成。

有关简单词搜索的详细信息

在全文搜索中,单词(或标记)是其边界由相应的断字符标识、遵循指定语言的语言规则的字符串。 有效的短语由多个单词组成,单词之间可以有标点符号也可以没有标点符号。

例如,“croissant”是一个词,“café au lait”是一个短语。 这样的词和短语称为“简单词”。

CONTAINSCONTAINSTABLE 会查找与该短语完全匹配的结果。 FREETEXTFREETEXTTABLE 将短语拆分为几个词。

搜索带有某个前缀的单词(前缀词)

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

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

将会返回所有与星号 (*) 之前指定的文本相匹配的文本。 如果未在文本和星号前后加上双引号标记(如 CONTAINS (DESCRIPTION, 'top*')),则全文搜索将不把星号当作通配符。

当前缀词是短语时,组成该短语的每个标记均被看作是单独的前缀词。 将返回包含以这些前缀词开头的词的所有行。 例如,前缀词项“light bread*”将找到包含“裹有少量面包屑的”“轻微裹粉的”或“light bread”这些文本的行,但不会返回“轻微烘烤过的面包”。

有关前缀搜索的详细信息

前缀词指附加到一个单词的前面以生成一个派生词或变形的字符串。

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

  • 如果是短语,则该短语内的每个词都被看作是一个前缀。 例如,术语“auto tran*”可以匹配到“automatic transmission”(自动变速器)和“automobile transducer”(汽车换能器),但不能匹配到“automatic motor transmission”(自动发动机传动装置)。

CONTAINSCONTAINSTABLE 支持前缀搜索。

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

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

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

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

全文搜索使用词干提取器,从而可以搜索同一动词的不同时态和变位形式,或同一名词的单数和复数形式。 有关词干分析器的更多信息,请参阅 配置和管理搜索的分词符和词干分析器

有关生成词搜索的更多信息

屈折形式是指动词的不同时态和变位形式,或名词的单数和复数形式。

例如,搜索词“drive”的变形。如果表中不同的行包含词“drive”、“drives”、“drove”、“driving”和“driven”,则这些词都会出现在结果集中,原因是它们每一个都可以从词 drive 变形而来。

FREETEXTFREETEXTTABLE 默认情况下查找所有指定词的变形。 CONTAINSCONTAINSTABLE 支持可选的 INFLECTIONAL 参数。

搜索特定词的同义词

同义词库为词定义用户指定的同义词。 有关同义词库文件的详细信息,请参阅为全文搜索配置和管理同义词库文件

例如,如果将条目“{car, automobile, truck, van},”添加到同义词库,则可以搜索 单词“car”的同义词库形式。由于这些单词中的每一个都属于包含单词“car”的同义词扩展集,因此在所查询的表中所有包括单词“automobile”、“truck”、“van”或“car”的行都会出现在结果集中。

FREETEXTFREETEXTTABLE 默认情况下使用同义词库。 CONTAINSCONTAINSTABLE 支持可选的 THESAURUS 参数。

搜索与另一个词相邻的词

邻近词表示词或短语彼此相邻。 还可以指定分隔第一个和最后一个搜索词之间的非搜索词的最大数量。 此外,可以以任意顺序或您指定的顺序搜索词或短语。

例如,您想查找其中单词“冰”与“曲棍球”彼此邻近,或者短语“滑冰”与“冰球”彼此邻近的行。

CONTAINSCONTAINSTABLE

有关邻近搜索的详细信息,请参阅使用 NEAR 搜索与另一个词邻近的词

使用加权值搜索词语或短语(加权术语)

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

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

USE AdventureWorks2022  
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  

加权词可以与任意简单词、前缀词、派生词或邻近词一起使用。

有关加权词搜索的详细信息

在加权词搜索中,加权值指示一组单词和短语中的每个单词和短语的重要程度。 加权值的最低值是 0.0,最高值是 1.0。

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

CONTAINSTABLE 支持加权词搜索。

使用 AND、OR 和 NOT(布尔运算符)

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)

示例

以下示例使用 CONTAINS 谓词搜索描述 ID 不等于 5,且描述中同时包含单词“Aluminum”和单词“spindle”的描述。该搜索条件使用 AND 布尔运算符。 下面的示例使用 AdventureWorks2025 数据库的 ProductDescription 表。

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

大小写、停用词、语言和同义词库

编写全文查询时,还可以指定以下选项:

  • 区分大小写。 全文搜索查询不区分大小写。 但是,在日语中,有许多表示语音的拼字法,其中拼字规范化这一概念与不区分大小写类似,如 kana = 不区分。 这种拼字规范化不受支持。

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

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

  • 同义词库。 FREETEXT 和 FREETEXTTABLE 查询默认情况下使用同义词库。 CONTAINS 和 CONTAINSTABLE 支持可选的 THESAURUS 参数。 有关详细信息,请参阅为全文搜索配置和管理同义词库文件

检查分词结果

在查询中应用给定的分词器、同义词库和停用词列表组合后,可以使用 sys.dm_fts_parser 动态管理视图查看全文搜索如何将结果标记化。 有关详细信息,请参阅 sys.dm_fts_parser (Transact-SQL)

另请参阅

CONTAINS (Transact-SQL)
CONTAINSTABLE (Transact-SQL)
FREETEXT (Transact-SQL)
FREETEXTTABLE (Transact-SQL)
创建全文搜索查询 (Visual Database Tools)
改进全文查询的性能