SQL Server全文搜索带逗号的数字字符串

时间:2015-05-12 20:35:42

标签: sql-server sql-server-2012 full-text-search

我在SQL Server 2012安装上有一个全文索引的nvarchar(max)列。如果该列的一行有'blah blah $ 1,234,567 blah blah'作为数据。当我运行以下查询时,将显示返回该行的查询:

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 *”返回结果而“1,234,5 *”和“1,234,56” *“ 不要。这是为什么?

1 个答案:

答案 0 :(得分:1)

此行为是由于如何处理数值以及将断字符应用于搜索词的组合。 简而言之,如果文字看起来像没有通配符的数字,那么它会被视为数字,否则会被视为字符串。

使用逗号搜索有效数字时,全文引擎会将其视为字符串和数字。您可以使用引擎用来解析搜索字符串的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不是有效数字,因此它被视为字符串。因此,它被逗号分开,并且各个值(123456)被标识为字符串或数字。它与您搜索"1" AND "234" AND "56*"相同。

解决此问题的一些想法:

  • 使用LIKE查询代替SELECT ftext FROM dbo.Test WHERE [ftext] LIKE '1,234,56%'
  • 预处理搜索字符串以从数字中删除逗号。