Sql-Server

無法理解全文結果的差異 - 包含、包含萬用字元、自由文本

  • August 10, 2020

我在名為 Filecontent 的列上有一個帶有全文索引的表。該表有一行內容包含“W 917”。對於上下文,此行上的內容列包含的不僅僅是我正在搜尋的內容。

我不明白為什麼我會得到不同的結果,具體取決於我使用的是包含、包含萬用字元還是自由文本。為什麼 CONTAINS without wildcard 得到結果,但 CONTAINS with wildcard 沒有?

-- Searching for "W 917"
-- No match - CONTAINS with wildcard
SELECT * FROM InvoicePDFContent t1 WHERE CONTAINS(t1.Filecontent, '"W 917*"')

-- Match - CONTAINS
SELECT * FROM InvoicePDFContent t1 WHERE CONTAINS(t1.Filecontent, '"W 917"')

-- Match - FREETEXT
SELECT * FROM InvoicePDFContent t1 WHERE FREETEXT(t1.Filecontent, '"W 917"')


-- Searching for "W"
-- Match - CONTAINS with wildcard
SELECT * FROM InvoicePDFContent t1 WHERE CONTAINS(t1.Filecontent, '"W*"')

-- No match - CONTAINS
SELECT * FROM InvoicePDFContent t1 WHERE CONTAINS(t1.Filecontent, '"W"')

-- No match - FREETEXT
SELECT * FROM InvoicePDFContent t1 WHERE FREETEXT(t1.Filecontent, '"W"')
´´´

差異是由雜訊詞“W”引起的。預設情況下,SQL Server 使用 stoplist 來排除一些簡短或常用的詞,例如“and”、“does”、“could”。您可以使用此類查詢查看完整列表:

select * from sys.fulltext_system_stopwords where language_id = 1033

如果需要,您可以禁用全文索引的停止列表。

現在讓我們看看您的查詢:

SELECT * FROM InvoicePDFContent t1 WHERE CONTAINS(t1.Filecontent, '"W*"')

這個查找包含以“W”開頭的單詞的所有行,這些單詞不應該在您的停止列表中。

SELECT * FROM InvoicePDFContent t1 WHERE CONTAINS(t1.Filecontent, '"W"')

此查詢不返回任何內容,因為您正在尋找停用詞。

SELECT * FROM InvoicePDFContent t1 WHERE CONTAINS(t1.Filecontent, '"W 917"')

此查詢只是忽略 W 並查找“917”。

SELECT * FROM InvoicePDFContent t1 WHERE CONTAINS(t1.Filecontent, '"W 917*"')

這是最有趣的案例。根據 SQL Server 文件:

當 <prefix_term> 是一個片語時,片語中包含的每個單詞都被認為是一個單獨的前綴。因此,指定前綴詞“local wine*”的查詢匹配任何帶有“local winery”、“locally wined and dined”等文本的行。

這意味著實際上您正在尋找連續有兩個單詞的片語。第一個類似於“W*”(但它不應該在停止列表中),第二個是“917*”。

引用自:https://dba.stackexchange.com/questions/273500