我们有一个 InnoDB 表 post
,并在两列 title
和 content
上用 ngram 解析器。
大部分数据是汉字,但包含一些日文和英文字符。
我们使用 MySQL 8.0.15 并且我已经将 innodb_ft_min_token_size
值设置为 1。现在我想做这样的事情:
SELECT * FROM `post` WHERE MATCH (`title`, `content`) AGAINST ('e');
expected result:
title content
------------------------
Food noodle
或真实案例:
SELECT * FROM `post` WHERE MATCH (`title`, `content`) AGAINST ('麵');
expected result:
title content
------------------------
本週推薦美食 到底該吃飯還是麵
在英文里是没有意义的,但是在中文里有时候一个字是有意义的。
但是,当我搜索单个字符时,它会返回一个空集。仅对于一些特殊字符,如日文字符 su
和 し
,以 bool 模式返回一些结果(它不会返回包含该字符的所有行)。
我尝试在 bool 模式下使用通配符和查询,但当搜索字符是句子的最后一个字符时,它不起作用。
我还尝试将 ngram_token_size
设置为 1。它显示了一个奇怪的结果:所有常规搜索查询均未返回任何内容,而那些特殊字符仍然如上所述有效。但是如果我用 WITH QUERY EXPANSION
语法搜索那些特殊字符,这一次它将返回比 bool 模式更多的结果(我不确定这些是否都是包含该字符的行)。
是否可以使用单个字符进行全文搜索?
最佳答案
我不确定这是否是 CJK 语言或 ngram 解析器的特例。 按特定顺序创建/重建全文索引似乎会导致某些问题。
建表时建立全文索引,然后再插入数据就好了。
然而,在我的例子中,表中已经存在一些数据。然后我使用 ALTER TABLE post ADD FULLTEXT ft_search_index(title, CONTENT) WITH PARSER ngram;
来构建索引。
(如果我按照这个顺序建立索引还有一个问题,一些搜索查询在 bool 模式下无法匹配所有预期结果)
回到问题...
是的,可以使用单个字符进行全文搜索。您应该将 ngram_token_size
设置为 1。
但是在重建索引的时候出现了一些问题。
根据document ,更改设置后,我可以使用 ALTER TABLE
重建索引。
但是不管我用这个语法做什么
ALTER TABLE post DROP INDEX ft_search_index, ADD FULLTEXT ft_search_index(title, content) WITH parser ngram;
(造成了我问题中提到的情况)
或者拆分成两个句子
ALTER TABLE post DROP INDEX ft_search_index;
ALTER TABLE post ADD FULLTEXT ft_search_index(title, content) WITH parser ngram;
,
两者都不能很好地工作。
这是我的解决方案:
之后,我尝试运行 OPTIMIZE
语法来重建索引(如 document 中所述,这也会重建索引)。
OPTIMIZE TABLE post;
它没有这些问题。
(在为大型表运行 OPTIMIZE TABLE
之前检查 innodb_optimize_fulltext_only
和 innodb_ft_num_word_optimize
)
关于MySQL - 如何使用全文索引搜索单个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57231378/