SQL Server全文搜索包含连字符的短语不会返回预期结果

时间:2012-07-25 04:46:15

标签: sql sql-server sql-server-2008 tsql full-text-search

我们有一个使用SQL Server 2008数据库和全文搜索的应用程序。我试图理解为什么以下搜索的行为不同:

首先,一个包含连字符的短语,如下所示:

contains(column_name, '"one two-three-four five"')

第二,一个相同的短语,连字符被空格替换:

contains(column_name, '"one two three four five"')

全文索引使用ENGLISH(1033)语言环境和默认系统停止列表。

根据我对包含带连字符的单词的其他全文搜索的观察,第一个应该允许one two three four fiveone twothreefour five上的匹配。相反,它只匹配one twothreefour five(而不是one two-three-four five)。


测试用例

设定:

create table ftTest 
(
    Id int identity(1,1) not null, 
    Value nvarchar(100) not null, 
    constraint PK_ftTest primary key (Id)
);

insert ftTest (Value) values ('one two-three-four five');
insert ftTest (Value) values ('one twothreefour five');

create fulltext catalog ftTest_catalog;
create fulltext index on ftTest (Value language 1033)
    key index PK_ftTest on ftTest_catalog;
GO

查询:

--returns one match
select * from ftTest where contains(Value, '"one two-three-four five"')

--returns two matches
select * from ftTest where contains(Value, '"one two three four five"')
select * from ftTest where contains(Value, 'one and "two-three-four five"')
select * from ftTest where contains(Value, '"one two-three-four" and five')
GO

清理:

drop fulltext index on ftTest
drop fulltext catalog ftTest_catalog;
drop table ftTest;

3 个答案:

答案 0 :(得分:8)

http://support.microsoft.com/default.aspx?scid=kb;en-us;200043

“如果必须在搜索标题中使用非字母数字字符(主要是短划线' - '字符),请使用Transact-SQL LIKE子句而不是FULLTEXT或CONTAINS谓词。”

答案 1 :(得分:5)

在这些情况下,你无法预料断字符的行为,在你的字符串上运行sys.dm_fts_parser总是一个好主意,以便了解这些单词将如何分割并存储在内部指数。

例如,在“一二三四五”上运行sys.dm_fts_parser会产生以下结果 -

select * from sys.dm_fts_parser('"one two-three-four five"', 1033, NULL, 0)
--edited--
1   0   1   Exact Match one
1   0   2   Exact Match two-three-four
1   0   2   Exact Match two
1   0   3   Exact Match three
1   0   4   Exact Match four
1   0   5   Exact Match five

从返回的结果中可以看出,断字符解析字符串并输出六种形式,这些形式可以解释运行CONTAINS查询时看到的结果。

答案 2 :(得分:2)

全文搜索将单词视为不带空格或标点符号的字符串。非字母数字字符的出现可以在搜索期间“破坏”单词。由于SQL Server全文搜索是基于单词的引擎,因此通常不会考虑标点符号,并且在搜索索引时会忽略标点符号。因此,像'CONTAINS(测试,“计算机失败”)这样的CONTAINS子句会将一行与值匹配,“找不到我的计算机将会很昂贵。”

请按照以下链接进行操作:https://support.microsoft.com/en-us/kb/200043