全文檢索述詞與函數概觀

全文檢索查詢會使用全文檢索述詞 (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 字串」(Freetext String)) 的意義,但不比對確切的用字。如果在指定之資料行的全文檢索索引中找到任何詞彙或任何形式的詞彙,就會產生相符項目。

若要針對連結的伺服器執行查詢,您可以在 CONTAINS 或 FREETEXT 中使用四個部分的名稱。如需詳細資訊,請參閱<查詢連結的伺服器 (全文檢索搜尋)>。

如需有關這些述詞之語法和引數的詳細資訊,請參閱<CONTAINS (Transact-SQL)>和<FREETEXT (Transact-SQL)>。

[!附註]

當資料庫相容性層級設定為 100 時,OUTPUT 子句中不允許全文檢索述詞。

範例

A. 搭配 <simple_term> 使用 CONTAINS

下列範例會尋找所有價格是 $80.99,且含有 "Mountain" 這個單字的產品。

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 資料行會傳回每個資料列的「等級值」(Rank Value),表示資料列與選取準則的符合程度。資料列中文字或文件的等級值越高,該資料列與給定全文檢索查詢的關聯性就越大。請注意,不同的資料列可能會以完全相同的方式排序等級。您可以透過指定選擇性 top_n_by_rank 參數,限制要傳回的相符項目數。如需詳細資訊,請參閱<限制等級排序結果集 (全文檢索搜尋)>和<搜尋查詢結果如何排序等級 (全文檢索搜尋)>。

使用其中一個函數時,您必須指定要進行全文檢索搜尋的基底資料表。與述詞一樣,您可以指定要搜尋資料表中的單一資料行、資料行清單或所有資料行,而且可以選擇性地指定給定全文檢索查詢將使用之資源的語言。

CONTAINSTABLE 適用的比對種類與 CONTAINS 相同,而 FREETEXTTABLE 適用的比對種類則與 FREETEXT 相同。如需詳細資訊,請參閱本主題前面的全文檢索述詞 (CONTAINS 和 FREETEXT) 的概觀。執行使用 CONTAINSTABLE 和 FREETEXTTABLE 函數的查詢時,您必須明確聯結所傳回的資料列與 SQL Server 基底資料表中的資料列。

如需有關這些函數之語法和引數的詳細資訊,請參閱<CONTAINSTABLE (Transact-SQL)>和<FREETEXTTABLE (Transact-SQL)>。

範例

A. 使用 CONTAINSTABLE

下列範例將傳回所有食物種類的描述與類別名稱,其中 Description 資料行包含 "sweet and savory" 的單字,近似於 "sauces" 或 "candies"。所有類別目錄名稱是 "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 述詞來搜尋描述識別碼不等於 5,而且描述同時包含 "Aluminum" 與 "spindle" 這兩個單字的描述。搜尋條件會使用 AND 布林運算子。

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

其他考量

每個啟用全文檢索的資料表都具有一個用來強制資料表之唯一資料列的資料行 (「唯一索引鍵資料行」(Unique Key Column))。撰寫 CONTAINSTABLE 或 FREETEXTTABLE 類型的全文檢索查詢時,您需要使用唯一索引鍵資料行的名稱。如需詳細資訊,請參閱<如何:查詢全文檢索索引鍵資料行 (Transact-SQL)>。

許多查詢詞彙主要取決於斷詞工具行為。若要確保您使用正確的斷詞工具 (和字幹分析器) 和同義字檔案,我們建議您指定 LANGUAGE 引數。如需詳細資訊,請參閱<建立全文檢索索引時選擇語言的最佳作法>。

定義全文檢索查詢時,全文檢索引擎會從搜尋準則中捨棄停用字詞 (也稱為非搜尋字)。停用字詞是指 "a"、"and"、"is" 或 "the" 等字,這些字雖然經常出現,但通常對搜尋特定文字並無幫助。停用字詞會列於停用字詞表中。每個全文檢索索引都會與特定停用字詞表相關聯,以便判斷哪些停用字詞會在建立索引時,從查詢或索引中省略。如需詳細資訊,請參閱<停止字詞和停止清單>。

根據預設,同義字比對會針對指定 FORMSOF THESAURUS 子句的 CONTAINS 和 CONTAINSTABLE Transact-SQL 查詢以及 FREETEXT 和 FREETEXTABLE 查詢進行。