SQL 服务器上的全文搜索具有区分大小写的行为

Full-text search on SQL Server has case-sensitive behavior

我有一个包含空非索引字表的全文索引。

table 包含一个值为 'A. Beta' 的行。如果我搜索 'A. Beta' 或 'A. beta'(使用全文搜索),该行会正确显示。但是,如果我搜索 'a. Beta' 或 'a. beta',该行不会显示。

这是怎么回事?有没有好的解决方法?在将搜索字符串发送到数据库之前,我可以从搜索字符串中删除句点,但是还有什么我应该删除的吗?

示例:

CREATE TABLE mytable (
    id BIGINT IDENTITY NOT NULL, 
    name VARCHAR(256) NOT NULL,
    CONSTRAINT mytable_pk PRIMARY KEY (id)
    );

CREATE FULLTEXT STOPLIST empty_stoplist;
CREATE FULLTEXT CATALOG mytable_catalog;
CREATE FULLTEXT INDEX ON mytable (
        name Language 1033
    )
    KEY INDEX mytable_pk
    ON mytable_catalog;
ALTER FULLTEXT INDEX ON mytable SET STOPLIST empty_stoplist;
ALTER FULLTEXT INDEX ON mytable START UPDATE POPULATION;

INSERT INTO mytable (name) VALUES ('A. Beta');

-- Wait until indexing is complete

SELECT * FROM mytable mt WHERE CONTAINS(mt.*, '"A. Beta"');
-- 1 result
SELECT * FROM mytable mt WHERE CONTAINS(mt.*, '"A. beta"');
-- 1 result
SELECT * FROM mytable mt WHERE CONTAINS(mt.*, '"a. Beta"');
-- 0 results
SELECT * FROM mytable mt WHERE CONTAINS(mt.*, '"a. beta"');
-- 0 results

运行 'A. Beta' 和 'a. Beta' 上的 fts 解析器给出了不同的结果。这可能是相关的:

-- Replace 7 with the id of 'empty_stoplist' or use NULL instead (same result).
select * from sys.dm_fts_parser('"A. Beta"', 1033, 7, 0)
-- keyword             group_id    phrase_id   occurrence  special_term     display_term  expansion_type  source_term
-- 0x0061              1           0           1           Exact Match      a             0               A. Beta
-- 0x0062006500740061  1           0           2           Exact Match      beta          0               A. Beta

对比

-- Replace 7 with the id of 'empty_stoplist' or use NULL instead (same result).
select * from sys.dm_fts_parser('"a. Beta"', 1033, 7, 0)
-- keyword             group_id    phrase_id   occurrence   special_term     display_term  expansion_type  source_term
-- 0x0061              1           0           1            Exact Match      a             0               a. Beta
-- 0xFF                1           0           9            End Of Sentence  END OF FILE   0               a. Beta
-- 0x0062006500740061  1           0           10           Exact Match      beta          0               a. Beta

问题实际上不是区分大小写,而是 a. Beta 中的句点,全文解析器将其解释为 "end of sentence"。换句话说,解析器正确地将 A.(大写)解释为缩写并忽略句点,但它认为 a.(小写)是句子的结尾而不是缩写,因为缩写通常大写英语。全文引擎在计算单词出现次数时使用句末标记和段末标记,以避免在匹配引用短语时出现误报。 (除了来自 How Search Query Results Are Ranked 的模糊声明外,我对出现次数计数的工作原理知之甚少:为了避免短语和邻近查询中的误报,句尾和结尾- of-paragraph 引入更大的出现间隙。)

解决此问题的最简单方法是从搜索字符串中删除句点。您会发现这两个搜索都会 return 您要查找的 1 个结果。

SELECT * FROM mytable mt WHERE CONTAINS(mt.*, '"A Beta"');

SELECT * FROM mytable mt WHERE CONTAINS(mt.*, '"a Beta"');

根据微软 documentation :

Full-text queries are not case-sensitive. For example, searching for "Aluminum" or "aluminum" returns the same results.

问题与搜索条件以及查询的解析方式有关,如@Keith 所回答。