比较全文函数与全文谓词

CONTAINSTABLE 和 FREETEXTTABLE 函数用来指定全文查询以返回每行的相关性排名。这两个函数与全文谓词 CONTAINS 和 FREETEXT 非常相似,但是用法不同。

虽然全文谓词和全文函数都用于全文查询,且二者用来指定全文搜索条件的语法是一样的,但是它们在使用方法上仍有显著差别。下面列出了一些重要的相似处和不同处:

  • CONTAINS 和 FREETEXT 都返回 TRUE 或 FALSE 值,并且都在 SELECT 语句的 WHERE 或 HAVING 子句中指定。
  • CONTAINSTABLE 和 FREETEXTTABLE 都返回包含零行、一行或多行的表,因此它们必须始终在 FROM 子句中指定。
  • CONTAINS 和 FREETEXT 只能用于指定选择条件,Microsoft SQL Server 将使用该条件来确定结果集的成员身份。
  • CONTAINSTABLE 和 FREETEXTTABLE 也用来指定选择条件。返回的表中有一个名为 KEY 的列,其中包含全文键值。每个全文注册表必定会有某一列的值是唯一的。在 CONTAINSTABLE 或 FREETEXTTABLE 返回的全文注册表中,KEY 列中的值是与全文搜索条件中所指定的选择条件匹配的行的唯一值。

此外,CONTAINSTABLE 和 FREETEXTTABLE 生成的表中还有一个名为 RANK 的列,其中包含从 0 到 1000 的值。值越小,相关性越低。根据返回的行与选择条件的匹配程度,使用这些值对行进行排名。

ms142494.note(zh-cn,SQL.90).gif注意:
排名值仅指示结果集中各行相关性的相对顺序。实际的值并不重要,并且每次运行查询时返回的值都不会相同。有关排名的详细信息,请参阅理解排名的概念

CONTAINS 和 FREETEXT 查询不会返回任何排名值。

使用 CONTAINSTABLE 和 FREETEXTTABLE 函数运行查询时,必须将返回的限定行与原始 SQL Server 表中的行显式联接。

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

ms142494.note(zh-cn,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 查询,以便首先返回排名最高的行,并将每一行的排名添加到选择列表中。若要指定该查询,必须知道 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

标识唯一键列名称

编写使用赋值行集函数的查询时,必须知道唯一键列的名称。每个启用全文查询的表都具有 TableFulltextKeyColumn 属性,该属性包含用来标识该表的不同行的列的 ID。以下示例说明了如何通过编程方式获取该键列的名称。

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(zh-cn,SQL.90).gif注意:
使用 top_n_by_rank 参数将返回满足全文查询的行的子集。如果 top_n_by_rank 与其他谓词组合使用,则查询返回的行数可能会少于与所有谓词实际匹配的行数。

Microsoft SQL Server 将使用这些信息按排名对匹配项进行排序,并最多只返回指定数目的匹配项。这样可以大幅度提高性能。例如,对于正常情况下会从一个包含一百万行的表中返回 100,000 行的查询,如果只要求返回前 100 行,此查询的处理速度会更快。

在前面使用 CONTAINSTABLE 的示例中,如果只想返回前 3 个匹配项,该查询将如下所示:

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 列中词“sauces”或“candies”附近存在词“sweet and savory”。

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 帮助