让我们考虑 User.Note ='Version:3.7.21.1'
SELECT * FROM [USER] WHERE CONTAINS(NOTE, '"3.7.2*"')
=>返回某些内容
SELECT * FROM [USER] WHERE CONTAINS(NOTE, '"3.7*"')
=>返回不显示
如果 User.Note ='Version:3.7.21'
SELECT * FROM [USER] WHERE CONTAINS(NOTE, '"3.7*"')
=>返回某些内容
如果 User.Note ='Version:3.72.21'
SELECT * FROM [USER] WHERE CONTAINS(NOTE, '"3.7*"')
=>返回不显示
我不知道它是如何工作的。当我搜索“ 3.7 *”时,它应该总是返回一些信息。
您知道这背后的逻辑是什么吗?
PS:如果我用字母替换数字,那没问题。
答案 0 :(得分:3)
我认为您的问题是由断字器与数据中的标点符号交互作用的不可预测性引起的。全文搜索基于字符串的概念,不包括空格和标点符号。当引擎建立索引时,它会看到句点并以怪异的方式破坏单词。
作为示例,我用您提供的三个值制作了一张小桌子...
VALUES (1,'3.7.21.1'),(2,'3.7.21'),(3,'3.72.21')
现在,当我进行选择时,我会在所有四个结果上得到……虽然不是我期望的结果。
对我来说,这将返回所有三个值
SELECT * FROM containstext WHERE CONTAINS(secondid, '"3.7.2*"')
,这仅返回 3.7.21
SELECT * FROM containstext WHERE CONTAINS(secondid, '"3.7*"')
让我们运行它,看看全文索引的内容
SELECT * FROM sys.dm_fts_index_keywords(db_id('{databasename}'), object_id('{tablename}'))
对于我的结果(您可能完全不同),我具有以下display_term值
display_term document_count
21 3
3 3
3.7.21 1
7 2
72 1
因此,让我们看一下第一个搜索条件'"3.7.2*"'
如果我将其推入sys.dm_fts_parser
...
select * from sys.dm_fts_parser('"3.7.2*"', 1033, NULL, 0)
...这表明它在
上因匹配而中断3
7
2
但如果我这样做...
select * from sys.dm_fts_parser('"3.7*"', 1033, NULL, 0)
我在术语3.7
和sys.dm_fts_index_keywords
上有一个完全匹配的词,之前我告诉我只有一个包含3.7
的文档/行
您还可能会感到更加怪异,因为数字0-9通常在系统停用词中,并且由于被认为是无用的而可以被排除在索引之外。这可能就是为什么当您更改为字母时它会起作用的原因。
此外,我知道您已决定替换LIKE,但是Microsoft suggested表示您在全文索引中仅使用字母数字字符,并且,如果需要在搜索条件中使用非字母数字字符,则可以应该使用LIKE。也许将句点更改为正常值中不会使用的某些字母数字替换?
答案 1 :(得分:0)
仅当该列在全文索引中时,内容才有效。如果它没有被索引,则您将需要使用:
SELECT * FROM [USER] WHERE NOTE like '3.7%' --or '%3.7%
是否要使用CONTAINS,因为您认为它会更快?(通常是这样)
Microsoft文档列出了格式化和使用CONTAINS的所有方法(11个示例)