Mat*_*ker 9 sql sql-server full-text-search
使用SQL Server 2012(通常使用SQL Server 2008 R2到SQL Server 2016)
此问题是SQL-Server全文索引意外结果的更具体的重写.请看这里我们如何达到这一点以及已经尝试过的方法.
我现在重新发帖我们发现了具体的错误.非常感谢@HoneyBadger.
到目前为止,他的帮助非常宝贵.
表结构:
CREATE TABLE TestFullTextSearch (Id INT NOT NULL, AllText NVARCHAR(400))
CREATE UNIQUE INDEX test_tfts ON TestFullTextSearch(Id)
CREATE FULLTEXT CATALOG ftcat_tfts
CREATE FULLTEXT INDEX ON TestFullTextSearch(AllText)
KEY INDEX test_tfts ON ftcat_tfts
WITH CHANGE_TRACKING AUTO, STOPLIST OFF
Run Code Online (Sandbox Code Playgroud)
数据:
INSERT INTO TestFullTextSearch
VALUES (1, ' 123_456 789 '), (2, ' 789 123_456 '),
(3, ' 123_456 ABC '), (4, ' ABC 123_456 ')
Run Code Online (Sandbox Code Playgroud)
请注意,此数据纯粹是为了证明问题,并不代表实时数据集.我们的实时数据集可以超过500,000行,搜索单个字段中的数据段 - 因此使用全文搜索.
按预期选择1:结果
SELECT *
FROM TestFullTextSearch
WHERE CONTAINS (AllText, '"123*"')
Id AllText
----------- ------------
1 123_456 789
2 789 123_456
3 123_456 ABC
4 ABC 123_456
Run Code Online (Sandbox Code Playgroud)
SELECT 2:错过结果集中的第2行
SELECT *
FROM TestFullTextSearch
WHERE CONTAINS (AllText, '"123_*"')
Id AllText
----------- ------------
1 123_456 789
3 123_456 ABC
4 ABC 123_456
Run Code Online (Sandbox Code Playgroud)
SELECT 3:仅返回第2行
SELECT *
FROM TestFullTextSearch
WHERE CONTAINS (AllText, '"123\_*"')
Id AllText
----------- ------------
2 789 123_456
Run Code Online (Sandbox Code Playgroud)
结论:如果前面的单词是数字字符串,则搜索带有下划线的数字字符串会失败.
问题:我们的客户使用全文搜索,并期望在零件编号和目录参考周围出现结果,这些结果可能包含或不包含在包含其他数字字符串的文本部分中.全文搜索似乎不以一致的方式支持这一点.
任何帮助感激不尽.
注意:这个问题不会发生在SQL SERVER 2008上,而是发生在2012+上
我也试过切换到旧版本的FTS解析器.测试用
SELECT * FROM sys.dm_fts_parser (' "789 123_456" ',1033,0,0)
SELECT * FROM sys.dm_fts_parser (' "789 123_456" ',2057,0,0)
Run Code Online (Sandbox Code Playgroud)
所以它产生了影响,但我仍然得到相同的结果.
在2008年和2012年之间的全文搜索中是否存在其他可能产生这种影响的差异?
They changed the full text parsers/stemmers between SQL 2008 and SQL 2012.
With a registry change, you can use the legacy parser, which should work better in your situation.
See https://technet.microsoft.com/en-us/library/gg509108(v=sql.110).aspx for details.
If you need to support both old and new style, then you can revert US English to the old and keep UK English the new (or vice versa)
Using SQL 2016, I reverted UK English and kept US English the same:
exec sp_help_fulltext_system_components 'wordbreaker', 1033
exec sp_help_fulltext_system_components 'wordbreaker', 2057
Run Code Online (Sandbox Code Playgroud)
I created another table using UK English and populated it.
CREATE TABLE TestFullTextSearch2 (Id INT NOT NULL, AllText NVARCHAR(400))
CREATE UNIQUE INDEX test_tfts2 ON TestFullTextSearch2(Id)
CREATE FULLTEXT INDEX ON TestFullTextSearch2(AllText language 2057)
KEY INDEX test_tfts2 ON ftcat_tfts
WITH CHANGE_TRACKING AUTO, STOPLIST OFF
INSERT INTO TestFullTextSearch2
VALUES (1, ' 123_456 789 '), (2, ' 789 123_456 '),
(3, ' 123_456 ABC '), (4, ' ABC 123_456 ')
Run Code Online (Sandbox Code Playgroud)
I'm getting the expected 4 results for all 3 queries.
确认您的更改已生效。
exec sp_help_fulltext_system_components 'wordbreaker', 1033
exec sp_help_fulltext_system_components 'wordbreaker', 2057
select t.name, c.* from sys.tables t inner join sys.fulltext_index_columns c on t.object_id = c.object_id
Run Code Online (Sandbox Code Playgroud)