SQL 服务器全文搜索带逗号的数字字符串
SQL Server Full Text search for numeric string with commas
我在 SQL Server 2012 安装中有一个全文索引的 nvarchar(max) 列。如果该列的一行有 'blah blah ,234,567 blah blah' 作为数据。当我 运行 以下查询时,显示 return 行的查询:
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1,234,567*"') --true
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1234567*"') --true
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1,234*"') --true
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1234*"') --true
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1,234,5*"') --false
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"12345*"') --true
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1,234,56*"') --false
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"123456*"') --true
起初我只是假设逗号被视为噪音,但事实似乎并非如此,因为“1,234,567*”和“1,234*”return 是结果,而“1,234,5* " 和 "1,234,56*" 没有。这是为什么?
此行为是由于数字值的处理方式以及分词系统应用于搜索词的方式共同造成的。 简而言之,如果文本看起来像没有通配符的数字,则将其视为数字,否则将视为字符串。
当使用逗号搜索有效数字时,全文引擎会将其同时视为字符串和数字。您可以通过使用引擎用来解析搜索字符串的 sys.dm_fts_parser 来查看实际效果。例如,这里是 SELECT display_term FROM sys.dm_fts_parser (' "1,234,567*" ', 1033, 0, 0)
:
的结果
display_term
---------------------
1,234,567 <-- string
nn1234567 <-- number
我有点不确定 1,234,567
是如何存储在全文索引中的——它将是上面列出的上述值之一或两者——但无论如何,很容易看出 "1,234,567*"
将在索引中找到匹配项。
现在让我们试试"1,234,56*"
。 SELECT * FROM sys.dm_fts_parser (' "1,234,56*" ', 1033, 0, 0)
的结果是:
display_term
---------------------
1
nn1
234
nn234
56
nn56
哇,发生什么事了?嗯,1,234,56
不是一个有效的数字,所以它被当作一个字符串来处理。因此,它由逗号分隔,并且各个值(1
、234
、56
)被标识为字符串或数字。这与搜索 "1" AND "234" AND "56*"
.
一样
解决此问题的一些想法:
- 改为使用 LIKE 查询
SELECT ftext FROM dbo.Test WHERE [ftext] LIKE '1,234,56%'
- 预处理搜索字符串以从数字中删除逗号。
我在 SQL Server 2012 安装中有一个全文索引的 nvarchar(max) 列。如果该列的一行有 'blah blah ,234,567 blah blah' 作为数据。当我 运行 以下查询时,显示 return 行的查询:
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1,234,567*"') --true
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1234567*"') --true
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1,234*"') --true
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1234*"') --true
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1,234,5*"') --false
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"12345*"') --true
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"1,234,56*"') --false
SELECT ftext FROM dbo.Test WHERE Contains([ftext], '"123456*"') --true
起初我只是假设逗号被视为噪音,但事实似乎并非如此,因为“1,234,567*”和“1,234*”return 是结果,而“1,234,5* " 和 "1,234,56*" 没有。这是为什么?
此行为是由于数字值的处理方式以及分词系统应用于搜索词的方式共同造成的。 简而言之,如果文本看起来像没有通配符的数字,则将其视为数字,否则将视为字符串。
当使用逗号搜索有效数字时,全文引擎会将其同时视为字符串和数字。您可以通过使用引擎用来解析搜索字符串的 sys.dm_fts_parser 来查看实际效果。例如,这里是 SELECT display_term FROM sys.dm_fts_parser (' "1,234,567*" ', 1033, 0, 0)
:
display_term
---------------------
1,234,567 <-- string
nn1234567 <-- number
我有点不确定 1,234,567
是如何存储在全文索引中的——它将是上面列出的上述值之一或两者——但无论如何,很容易看出 "1,234,567*"
将在索引中找到匹配项。
现在让我们试试"1,234,56*"
。 SELECT * FROM sys.dm_fts_parser (' "1,234,56*" ', 1033, 0, 0)
的结果是:
display_term
---------------------
1
nn1
234
nn234
56
nn56
哇,发生什么事了?嗯,1,234,56
不是一个有效的数字,所以它被当作一个字符串来处理。因此,它由逗号分隔,并且各个值(1
、234
、56
)被标识为字符串或数字。这与搜索 "1" AND "234" AND "56*"
.
解决此问题的一些想法:
- 改为使用 LIKE 查询
SELECT ftext FROM dbo.Test WHERE [ftext] LIKE '1,234,56%'
- 预处理搜索字符串以从数字中删除逗号。