与符号 (&) 有问题
如何搜索包含与号 (&) 的单词(或句子)。
例如,在数据库中有:
1: "Johnson & Johnson"
2: "AT&T"
3: "Sample & Sample"
我应该如何编写全文搜索查询来搜索单个记录?
SELECT * from Companies c WHERE CONTAINS(c.CompanyName, '"AT&T"')
我知道字符 (&) 负责逻辑与运算。但我不知道如何使用全文搜索对其进行编码以在文本中搜索。
任何的想法?
与符号 (&) 有问题
如何搜索包含与号 (&) 的单词(或句子)。
例如,在数据库中有:
1: "Johnson & Johnson"
2: "AT&T"
3: "Sample & Sample"
我应该如何编写全文搜索查询来搜索单个记录?
SELECT * from Companies c WHERE CONTAINS(c.CompanyName, '"AT&T"')
我知道字符 (&) 负责逻辑与运算。但我不知道如何使用全文搜索对其进行编码以在文本中搜索。
任何的想法?
简短版:你不能(或者至少你可以,但你可能会得到比你预期更多的结果)
长版本:该字符'&'被视为“断字”,即当 SQL Server 遇到 an 时,'&'它会将其视为新“单词”(即标记)的开始。解析时 SQL Server 看到"AT&T"的是两个标记"AT"和"T".
您可以使用以下方法自行检查sys.dm_fts_parser:
SELECT * FROM sys.dm_fts_parser('AT&T', 1033, 0, 0)
keyword group_id phrase_id occurrence special_term display_term expansion_type source_term
----------- ----------- ----------- ----------- ------------- ------------- -------------- -----------
0x00610074 1 0 1 Noise Word at 0 AT
0x0074 2 0 1 Noise Word t 0 T
这意味着搜索与搜索"AT&T"几乎完全相同"AT T"。
这是设计使然,据我所知,修改此行为的唯一方法是安装您自己的分词器,但是我不建议这样做。
接受的答案并不完全正确。将搜索词括在双引号中会使单词分组成为“短语”匹配。在这种情况下,与号 ( &)可以被视为文字字符,例如当被一个或多个不构成已知单词的字母包围时。看看你的"AT&T"例子,我们看到:
DECLARE @Term NVARCHAR(100);
SET @Term = N'"AT&T"';
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1);
GO
回报:
keyword group phrase occurrence special display expansion source
id id term term type term
0x0061007400260074 1 0 1 Exact Match at&t 0 AT&T
正如您所看到的,与号完全没有问题,只要它包含在"您已经在做的双引号 ( ) 中,哇哦!
但是,对于示例来说,这并不干净"Johnson & Johnson":
DECLARE @Term NVARCHAR(100);
SET @Term = N'"Johnson & Johnson"';
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1);
GO
回报:
keyword group phrase occurrence special display expansion source
id id term term type term
0x006A006F0068006E0073006F006E 1 0 1 Exact Match johnson 0 Johnson & Johnson
0x006A006F0068006E0073006F006E 1 0 2 Exact Match johnson 0 Johnson & Johnson
这似乎也与搜索词匹配Johnson Johnson,这在技术上是不正确的。
因此,除了用双引号括起来之外,您还可以将 & 符号转换为下划线 ( _),其处理方式不同:
DECLARE @Term NVARCHAR(100);
SET @Term = N'"Johnson _ Johnson"';
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1);
GO
回报:
keyword group phrase occurrence special display expansion source
id id term term type term
0x006A006F0068006E0073006F006E 1 0 1 Exact Match johnson 0 Johnson _ Johnson
0x005F 1 0 2 Exact Match _ 0 Johnson _ Johnson
0x006A006F0068006E0073006F006E 1 0 3 Exact Match johnson 0 Johnson _ Johnson
并且,这样做一个字符翻译似乎不会对原始"AT&T"搜索产生不利影响:
DECLARE @Term NVARCHAR(100);
SET @Term = N'"AT_T"';
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0);
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1);
回报:
keyword group phrase occurrence special display expansion source
id id term term type term
0x00610074005F0074 1 0 1 Exact Match at_t 0 AT_T