MySQL 5.7.20 MyISAM中含逗号内容无法通过ngram全文索引搜索
MySQL全文索引搜索含逗号内容无结果的原因及解决办法
问题原因
核心问题出在ngram分词器对标点符号的处理逻辑,结合你的搜索方式导致无法匹配:
- 使用
ngram分词器时,MySQL会将逗号这类标点符号视为文本分隔符,对hi,there分词时会先拆分为hi和there两个独立单元。 - 由于
ngram_token_size=2,最终生成的索引token为:hi、th、he、er、re,完全不包含带逗号的token(如hi,或,t)。 - 你使用的
against('"hi,there"' in boolean mode)是精确匹配整个短语,但索引中根本没有hi,there这个完整的token,因此返回空结果。
验证过程(你的测试代码)
测试表数据
mysql> select * from tmp; +-----------------+ | book_name | +-----------------+ | hi,there | +-----------------+ 1 rows in set (0.00 sec)
失败的搜索语句
mysql> select book_name from tmp where match(book_name) against('"hi,there"' in boolean mode); Empty set (0.00 sec)
相关配置
mysql> show create table tmp; +-------+--------------+ | Table | Create Table | +-------+--------------+ | tmp | CREATE TABLE `tmp` ( `book_name` char(32) NOT NULL, FULLTEXT KEY `book_name` (`book_name`) /*!50100 WITH PARSER `ngram` */ ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 | +-------+--------------+ 1 row in set (0.00 sec) mysql> show variables like '%ngram%'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | ngram_token_size | 2 | +------------------+-------+ 1 row in set (0.01 sec)
解决办法
根据需求可选择以下方案:
- 精确匹配带逗号的内容(小数据量):直接用
LIKE绕过全文索引的分词限制:select book_name from tmp where book_name like '%hi,there%'; - 全文索引匹配包含目标词的记录:若不需要严格匹配逗号,仅需同时包含
hi和there,可调整搜索语句:select book_name from tmp where match(book_name) against('"hi" "there"' in boolean mode); - 修改存储与搜索规则(大数据量):将逗号替换为非分隔符字符(如下划线)后存入数据库,搜索时使用对应字符:
- 存储时预处理:
replace(book_name, ',', '_') - 搜索语句:
against('"hi_there"' in boolean mode)
- 存储时预处理:
内容的提问来源于stack exchange,提问作者Dodou Wang
相关产品推荐
相关产品推荐

