適用於:SQL Server
Azure SQL 資料庫
Azure SQL 受控執行個體
CONTAINSTABLE 與 FREETEXTTABLE 函式會回傳一個名為 RANK 0 至 1,000 的序數值(階級值)的欄位。 這些數值根據列與選擇標準的匹配度進行排名。 等級值僅表示結果集中資料列相關性的相對順序,其值越低表示相關性越低。 實際值並不重要,且每次查詢執行時通常都會有所不同。
注意
CONTAINS 和 FREETEXT 述詞不會傳回任何排名值。
符合搜尋條件的項目數通常會很大。 為避免CONTAINSTABLEFREETEXTTABLE查詢回傳過多匹配,請使用可選的 top_n_by_rank 參數。 它只回傳部分列。
top_n_by_rank 是一個整數值 n,表示只有 n 個排名最高的匹配會依降序回傳。 如果結合 top_n_by_rank 與其他參數,則查詢所傳回的資料列數目會少於實際符合所有述詞的資料列數目。
SQL Server Database Engine 會依排名排序匹配,並只回傳指定的列數。 例如,一個通常從 1,000,000 列資料表中回傳 100,000 列的查詢,如果只請求前 100 列,處理速度會更快。
使用 RANK 限制搜尋結果的範例
範例 A:只搜尋前三個相符項目
下列範例會使用 CONTAINSTABLE,以便只傳回前三個相符項目。
USE AdventureWorks2025;
GO
SELECT K.RANK,
AddressLine1,
City
FROM Person.Address AS A
INNER JOIN CONTAINSTABLE (Person.Address, AddressLine1, 'ISABOUT ("des*",
Rue WEIGHT(0.5),
Bouchers WEIGHT(0.9))', 3) AS K
ON A.AddressID = K.[KEY];
GO
結果集如下所示。
RANK Address City
----------- -------------------------------- ------------------------------
172 9005, rue des Bouchers Paris
172 5, rue des Bouchers Orleans
172 5, rue des Bouchers Metz
範例 B:搜尋前五個相符項目
下列範例會使用 CONTAINSTABLE 傳回在 Description 或 light 字附近包含 "aluminum" 一字的前五項產品之描述。
USE AdventureWorks2025;
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)', 5) AS KEY_TBL
ON FT_TBL.ProductDescriptionID = KEY_TBL.[KEY];
GO
搜尋查詢結果如何排序
全文搜尋可以產生一個可選的分數(或排名值),用以顯示全文查詢回傳資料的相關性。 此排名值會在每一列計算,並可作為排序準則,依相關性排序給定查詢的結果集。 等級值僅表示結果集中資料列相關性的相對順序。 實際的值並不重要,而且每次執行查詢後該值通常會不一樣。 排序值在查詢中沒有任何重要意義。
排序的統計資料
當你建立索引時,系統會收集統計數據以供排名。 建立全文目錄並不會直接建立單一索引結構。 取而代之的是,Full-Text 引擎在索引資料時會產生中間索引。 接著,全文檢索引擎會視需要將這些索引合併到較大的索引。 這個過程可以發生很多次。 接著,全文檢索引擎會執行「主要合併」,將所有的中繼索引合併至較大的主索引。
統計資料是在每個中繼索引層級中收集。 當索引被合併時,統計資料也會被合併。 某些統計資料值只能在主要合併程序期間產生。
雖然 資料庫引擎 會對查詢結果集進行排名,但它使用的統計數據來自最大的中間索引。 這種用法取決於中間索引是否合併。 因此,如果中繼索引並未合併,等級統計資料的精確度可能會有所變動。 這種準確度差異解釋了為何同一查詢隨著全文索引資料的加入、修改與刪除,以及較小索引合併,可能會回傳不同的排名結果。
為了降低索引大小與計算的複雜度,通常會將統計資料四捨五入。
下列清單包含一些計算等級時常用的重要詞彙與統計資料值。
| 術語 / 值 | 描述 |
|---|---|
| 屬性 | 資料列中的一個全文索引的資料行。 |
| Document | 在查詢中傳回的實體。 在 資料庫引擎 中,這對應於一列。 文檔可以有多種屬性,就像資料列可以有多個全文檢索的索引欄位。 |
| Index | 一或多個文件的單一反向索引。 它可能完全位於記憶體或磁碟中。 許多查詢統計資料會與符合項目的個別索引有關。 |
| 全文檢索目錄 | 被視為查詢的一個實體的中繼索引集合。 目錄是管理者視為組織單位的象徵。 |
| 字詞、權杖或項目 | 全文檢索引擎中的比對單位。 來自文件的文字串流會由特定語言的斷詞器切分成單字或權杖(token)。 |
| 出現次數 | 文件屬性中的文字位移,此文字位移由文字分隔來決定。 第一個字在位置 1,下個字在位置 2,依此類推。 為了避免片語查詢和鄰近查詢中出現偽陽性,句末和段落末端之間會產生較大的出現間距。 |
| TermFrequency | 鍵值連續出現的次數。 |
| IndexedRowCount | 已編製索引的資料列總數。 此值是根據中間索引中所維持的計數計算得出。 此數字在精確度上會有所不同。 |
| KeyRowCount | 含有指定索引鍵之全文檢索目錄的資料列總數。 |
| MaxOccurrence | 全文檢索目錄中針對特定屬性儲存在資料列中的發生次數最大值。 |
| MaxQueryRank | 最高等級為 1000,由 Full-Text 引擎返回。 |
等級計算問題
許多因素會影響排名計算的過程。 不同語言的文字在分隔 Token 化文字的方式上會有所差異。 例如,一個詞分解器會把「dog-house」字串拆成「dog」和「house」,但另一個詞分解器則把它當成「dog-house」。 匹配與排名會依指定語言而異,不僅詞彙不同,文件長度也不同。 文件長度的差異會影響所有查詢的等級。
統計資料 (例如 IndexRowCount ) 可能會有很大的差異。 例如,若一個目錄在主索引中有20億列,一個新文件會被索引到記憶體中的中介索引,根據記憶體中文件數量對該文件的排名可能會與主目錄文件的排名產生偏差。 因此,每次進行任何會導致大量資料列被編製索引或重新編製索引的資料填入作業後,請使用 ALTER FULLTEXT CATALOG ... REORGANIZE Transact-SQL 陳述式,將這些索引合併為主索引。 全文檢索引擎也會根據參數 (例如中繼索引的數目與大小) 來自動合併索引。
MaxOccurrence 值會正規化為 32 種範圍中的其中一種。 這種正規化意味著,例如,長度為 50 個詞的文件會被視為與長度為 100 個詞的文件相同。 下表顯示了正規化。 因為這兩份文件的長度在相鄰資料表值 32 到 128 的範圍內,因此會被視為長度同為 128 (32 <docLength<= 128)。
{ 16, 32, 128, 256, 512, 725, 1024, 1450, 2048, 2896, 4096, 5792, 8192, 11585,
16384, 23170, 28000, 32768, 39554, 46340, 55938, 65536, 92681, 131072, 185363,
262144, 370727, 524288, 741455, 1048576, 2097152, 4194304 };
CONTAINSTABLE 的等級
CONTAINSTABLE 等級會使用下列演算法:
StatisticalWeight = Log2( ( 2 + IndexedRowCount ) / KeyRowCount )
Rank = min( MaxQueryRank, HitCount * 16 * StatisticalWeight / MaxOccurrence )
短語匹配的排名與個別鍵相同,但 KeyRowCount (包含短語的列數)是一個估計值,可能不準確且高於實際數字。
NEAR 的等級
CONTAINSTABLE 支援使用 NEAR 選項來查詢彼此相近的兩個或多個搜尋字詞。 每個傳回之資料列的等級值是以許多參數為基礎。 其中一個主要排名因素是相對於文件長度的匹配項目 (或「命中次數」) 總數。 因此,例如,如果 100 個字的文件和 900 個字的文件包含完全相同的符合項目,100 個字的文件就會具有較高的等級。
資料列中每個搜尋結果的總長度也會根據該搜尋結果中第一個和最後一個搜尋字詞之間的距離影響該資料列的排名。 距離越小,命中對資料列的等級值貢獻就越大。 如果全文查詢未指定整數作為最大距離,僅包含距離超過 100 個邏輯項的命中紀錄,該文件的排名為 0。
ISABOUT 的等級
CONTAINSTABLE 支援使用 ISABOUT 選項來查詢加權詞彙。
ISABOUT 是傳統資訊擷取詞彙中的向量空間查詢。 預設使用的等級演算法是 Jaccard,這是一個相當有名的公式。 會針對查詢中的每個詞彙計算等級,然後進行結合,如以下演算法所述。
ContainsRank = same formula used for CONTAINSTABLE ranking of a single term (above).
Weight = the weight specified in the query for each term. Default weight is 1.
WeightedSum = Σ[key=1 to n] ContainsRankKey * WeightKey
Rank = ( MaxQueryRank * WeightedSum ) / ( ( Σ[key=1 to n] ContainsRankKey^2 )
+ ( Σ[key=1 to n] WeightKey^2 ) - ( WeightedSum ) )
FREETEXTTABLE 的等級
FREETEXTTABLE 等級是以 OKAPI BM25 等級公式為基礎。
FREETEXTTABLE 查詢是透過屈折產生(原始查詢詞的屈折形式)為查詢加入詞彙。 這些詞被視為獨立詞彙,與其產生詞彙無特殊關係。 由「同義字」功能產生的同義字會被視為獨立、且權重相等的詞彙。 查詢中的每個單字都是計算等級的基礎。
Rank = Σ[Terms in Query] w ( ( ( k1 + 1 ) tf ) / ( K + tf ) ) * ( ( k3 + 1 ) qtf / ( k3 + qtf ) ) )
Where:
w is the Robertson-Sparck Jones weight.
In simplified form, w is defined as:
w = log10 ( ( ( r + 0.5 ) * ( N - R + r + 0.5 ) ) / ( ( R - r + 0.5 ) * ( n - r + 0.5 ) )
N is the number of indexed rows for the property being queried.
n is the number of rows containing the word.
K is ( k1 * ( ( 1 - b ) + ( b * dl / avdl ) ) ).
dl is the property length, in word occurrences.
avdl is the average length of the property being queried, in word occurrences.
k1, b, and k3 are the constants 1.2, 0.75, and 8.0, respectively.
tf is the frequency of the word in the queried property in a specific row.
qtf is the frequency of the term in the query.