SQL Server 中全文搜索的奇怪行为
Posted
技术标签:
【中文标题】SQL Server 中全文搜索的奇怪行为【英文标题】:Strange behaviour with Fulltext search in SQL Server 【发布时间】:2013-11-23 13:00:40 【问题描述】:我有一个带有列消息 NVARCHAR(MAX) 的 MyTable。
ID 为 1 的记录包含消息“0123456789333444 测试”
当我运行以下查询时
DECLARE @Keyword NVARCHAR(100)
SET @Keyword = '0123456789000001*'
SELECT *
FROM MyTable
WHERE CONTAINS(Message, @Keyword)
记录 ID 1 出现在结果中,我认为它不应该出现,因为 0123456789333444 不包含 0123456789000001。
有人能解释为什么这些记录还是会显示吗?
编辑
select * from sys.dm_fts_parser('"0123456789333444 Test"',1033,0,0)
返回以下内容:
group_id phrase_id occurrence special_term display_term expansion_type source_term
1 0 1 Exact Match 0123456789333444 0 0123456789333444 Test
1 0 1 Exact Match nn0123456789333444 0 0123456789333444 Test
1 0 2 Exact Match test 0 0123456789333444 Test
【问题讨论】:
这看起来很像Contains() function falters with strings of numbers? 无论有无停止列表,我都无法在 SQL Server 2012 中重现这一点。你正在运行哪个版本,你的停止列表是什么(我知道你说这不是一个因素,但我仍然很好奇),以及包含“0123456789333444”的完整消息值是什么? 嗨@Keith,感谢您查看它。我正在使用 SQL Server 2008 R2。完整消息如上所示:'0123456789333444 测试'。你的意思是“你的停止名单是什么”?谢谢朱塞佩 @gsharp 在SSMS中右击表格,选择全文索引>属性,让我们知道“全文索引停止列表”的值是多少。 我开始认为这是 SS 2008 的问题,因为我无法在 SS 2012 中重现此问题,并且链接到的线程 @Love2Learn 也涉及 SS 2008。不幸的是我不能验证这一点,因为我没有安装 SS 2008。 【参考方案1】:这是因为@Keyword 没有用双引号括起来。这会强制进行零个、一个或多个匹配。
指定以开头的单词或短语的匹配 指定的文本。用双引号将前缀术语括起来 ("") 并在结束引号之前添加一个星号 (),这样 以星号前指定的简单术语开头的所有文本 是匹配的。该子句应以这种方式指定:CONTAINS (column, '"文本"')。星号匹配零个、一个或多个字符( 词或词组中的词根或词根)。如果文本和星号 没有用双引号分隔,所以谓词读作 CONTAINS (column, 'text*'),全文搜索将星号视为 一个字符并搜索与 text* 完全匹配的字符。全文 引擎将找不到带有星号 (*) 字符的单词,因为 分词器通常会忽略此类字符。
when 是一个短语,短语中包含的每个单词都是 被认为是一个单独的前缀。因此,一个查询指定一个 “local wine*”的前缀词匹配任何带有“local”文本的行 酒厂”、“在当地美酒佳肴”等等。
查看有关该主题的 MSDN。 MSDN
【讨论】:
感谢您的回答。我试过使用 SET @Keyword = '"0123456789000001*"' 但不幸的是结果是一样的。 能否请您发布您的 DDL 以创建全文索引。如果可能的话,我想看看。 这没什么大不了的:ALTER FULLTEXT INDEX ON [dbo].[MyTable] ADD ([Message]) 能否请您尝试删除星号。我今天再次重新阅读了 MSDN 文档,并查阅了有关该主题的 Microsoft 考试书籍。我想看看没有它的行为是什么。我没有可以为您运行全文测试的盒子,否则我会这样做。希望 cmets 可以帮助您找到解决方案。这是让你有点难过的好问题之一。所以它会是:SELECT...WHERE CONTAINS(Message, @Keyword)。 @Keyword 将设置为“0123456789000001”。请注意上面的 sn-p 中没有表示“零、一或更多”的酯符号。 直接使用这个字符串,不带变量是否有效?【参考方案2】:您是否尝试查询以下视图以查看系统停止列表中的内容?
select * from sys.fulltext_system_stopwords where language_id = 1033;
【讨论】:
通常的嫌疑人,但我的桌子上禁用了停用词。【参考方案3】:找到一个可行的解决方案。我添加了language 1033
作为附加参数。
SELECT * FROM MyTable WHERE CONTAINS(Message, @Keyword, langauge 1033)
【讨论】:
以上是关于SQL Server 中全文搜索的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章