我有一张items表,里面的title字段建立了全文本索引

select * from items WHERE MATCH(title) AGAINST ('+the' IN BOOLEAN MODE);
select * from items WHERE MATCH(title) AGAINST ('+what +if' IN BOOLEAN MODE);

默认配置下,这两个sql不会返回任何结果,而实际上数据库中是有对应数据的。
在这里插入图片描述

经过翻阅官方文档,是MySQL的全文本索引的机制导致的,使用默认配置的情况下,上面几个关键词恰好会失效,

解决办法

  1. 在原来的数据库创建一个空表

    create table ft_stopwords
    (
        value varchar(18) null
    );
    
  2. 去到MySQL配置文件my.cnf或者my.ini(取决你用哪个配置文件)的[mysqld]底下加上,my_db是我数据库的名称,替换成你自己的

    [mysqld]
    innodb-ft-server-stopword-table=my_db/ft_stopwords
    innodb_ft_min_token_size=0
    
  3. 重启MySQL服务器

  4. 删除并重建全文本索引

    drop index ix__fulltext__title on items;
    CREATE FULLTEXT INDEX ix__fulltext__title ON items (title);
    
  5. 完成,重新查找,就能得到想要的结果了。

下面解释一下究竟是什么机制导致的以及为什么这么配置。

全文本停用词

MySQL的全文本索引有一个“全文本停用词(Full-Text Stopwords)”的机制,默认启用。

这个机制有一张默认配置的停用词表

mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD;
+-------+
| value |
+-------+
| a     |
| about |
| an    |
| are   |
| as    |
| at    |
| be    |
| by    |
| com   |
| de    |
| en    |
| for   |
| from  |
| how   |
| i     |
| in    |
| is    |
| it    |
| la    |
| of    |
| on    |
| or    |
| that  |
| the   |
| this  |
| to    |
| was   |
| what  |
| when  |
| where |
| who   |
| will  |
| with  |
| und   |
| the   |
| www   |
+-------+
36 rows in set (0.00 sec)

恰好what、the都列出在其中。

我们的需求是要能够查到所有词包括what和the的结果,自然要将这两个词排除出这个列表。

按照文档给出的做法,需要我们自己在任意数据库加一张表,配有默认停用词表类似的结构,即要有value字段并且为varchar类型。

我们在原来的数据库创建一个空表,这样就不存在停用词了

create table ft_stopwords
(
    value varchar(18) null
);

接着去到mysql配置文件my.cnf或者my.ini,取决于你自己的配置,我这里的数据库叫做my_db在[mysqld]底下加上

innodb-ft-server-stopword-table=my_db/ft_stopwords

没有配置就直接把这个复制上去

[mysqld]
innodb-ft-server-stopword-table=my_db/ft_stopwords

重启服务器,看到下面的结果说明生效了。不过要使他生效于你的表,还得重建索引。这样无论查找的关键词是什么,都不会被列为停用词了。

mysql> SHOW VARIABLES LIKE 'innodb_ft_server_stopword_table';
+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| innodb_ft_server_stopword_table | my_db/ft_stopwords |
+-------------------------------+-----------------------+
1 row in set, 1 warning (0.00 sec)

全文本索引最大和最小字长

除了停用词表还有另外一个机制会导致无法得到结果——全文本索引最大和最小字长。

最大字长我们保持默认即可。而最小字长默认是4,我们要查找的if就短于这个长度从而失效了。对于innodb引擎而言,控制最小字长的配置参数是innodb_ft_min_token_size,将他配置为0,使所有词都能得到结果

[mysqld]
innodb_ft_min_token_size=0

重启MySQL服务器,看到这样的结果,说明对服务器生效了

mysql> SHOW VARIABLES LIKE 'innodb_ft_min_token_size';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_ft_min_token_size | 0     |
+--------------------------+-------+
1 row in set, 1 warning (0.00 sec)

这个配置同样需要重建索引才能已有的表中的索引生效

Logo

欢迎加入西安开发者社区!我们致力于为西安地区的开发者提供学习、合作和成长的机会。参与我们的活动,与专家分享最新技术趋势,解决挑战,探索创新。加入我们,共同打造技术社区!

更多推荐