SQL Server全文搜索&符号(&)

cza*_*rek 9 sql-server full-text-search ampersand

与&符有问题(&)

如何搜索包含&符号的单词(或句子).

例如,在数据库中有:

1: "Johnson & Johnson"
2: "AT&T"
3: "Sample & Sample"
Run Code Online (Sandbox Code Playgroud)

我应该如何编写全文搜索查询来搜索单个记录?

SELECT * from Companies c WHERE CONTAINS(c.CompanyName, '"AT&T"')
Run Code Online (Sandbox Code Playgroud)

我知道字符(&)负责逻辑AND操作.但我不知道如何编码它以使用全文搜索在文本中搜索.

任何的想法?

Jus*_*tin 8

简短版本:您不能(或者至少可以,但您可能得到比预期更多的结果)

长版本:该字符'&'被视为"断字符",即当SQL Server遇到'&'它时,它将其视为新"单词"(即令牌)的开头.解析时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
Run Code Online (Sandbox Code Playgroud)

这意味着搜索与搜索"AT&T"完全相同"AT T".

这是设计,据我所知,修改此行为的唯一方法是安装自己的断字器,但这不是我建议做的事情.


Sol*_*zky 5

接受的答案并不完全正确。用双引号将搜索词括起来使词组成为“短语”匹配。在这种情况下,与号 ( &)可以被视为文字字符,例如当被一个或多个不构成已知单词的字母包围时。看看你的"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
Run Code Online (Sandbox Code Playgroud)

返回:

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
Run Code Online (Sandbox Code Playgroud)

如您所见,与号完全没有问题,只要将它括在双引号 ( ") 中,您已经在这样做了,呜呼!

但是,对于"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
Run Code Online (Sandbox Code Playgroud)

返回:

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
Run Code Online (Sandbox Code Playgroud)

这似乎也匹配 的搜索词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
Run Code Online (Sandbox Code Playgroud)

返回:

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
Run Code Online (Sandbox Code Playgroud)

并且,这样做一个字符翻译似乎不会对原始"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);
Run Code Online (Sandbox Code Playgroud)

返回:

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
Run Code Online (Sandbox Code Playgroud)