MySQL中文全文全文索引的运用(innodb引擎)

全文索引是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。

从MySQL5.6版本开始支持InnoDB引擎的全文索引,语法层面上大多数兼容之前MyISAM的全文索引模式。5.7版本之后通过使用ngram插件开始支持中文。之前仅支持英文,因为是通过空格作为分词的分隔符,对于中文来说是不合适的。MySQL允许在char、varchar、text类型上建立全文索引。

MySQL支持三种模式的全文检索模式:

1、自然语言模式IN NATURAL LANGUAGE MODE)默认模式。

2、布尔模式IN BOOLEAN MODE,可以为检索的字符串增加操作符,例如“+”表示必须包含,“-”表示不包含,“*”表示通配符(这种情况, 即使传递的字符串较小或出现在停词中,也不会被过滤掉),其他还有很多特殊的布尔操作符,可以通过如下参数控制:

  1. +word: >一定要有(不含有该关键词的数据条均被忽略)。
  2. -word: 不可以有(排除指定关键词,含有该关键词的均被忽略)。
  3. >word: 提高该条匹配数据的权重值。
  4. <word: 降低该条匹配数据的权重值。
  5. ~word: 将其相关性由正转负,表示拥有该字会降低相关性(但不像 - 将之排除),只是排在较后面权重值降低。
  6. "word1 word2": 用双引号将一段句子包起来表示要完全相符,不可拆字。[给定单词必须出现在数据记录中,先后顺序也必须匹配,区分字母大小写]
  7. word*: 搜索以word开头的单词,只允许出现在单词的末尾
  8. (word1 word2): 括号用来将单词分成子表达式。括入括号的部分可以被嵌套

3、查询扩展模式WITH QUERY EXPANSION) 这种模式是自然语言模式下的一个变种,会执行两次检索,第一次使用给定的短语进行检索,第二次是结合第一次相关性比较高的行进行检索。[比如,对于单词database的查询,用户可能希望查询的不仅仅是包含database的文档,还指那些包含mysql、oracle、db2的单词。]

全文索引相关配置

以下测试来自mySQL5.7.22 for osx10.12。版本不同可能会有些差异。

MySQL全文索引最小索引长度可以通过配置文件my.conf来配置, MyISAM通过配置 ft_min_word_len (默认是4)来修改最小索引长度。innodb需要修改 ft_min_word_len (默认是3)修改最小索引长度。还能使用 ft_max_word_len (默认是84)修改最大索引长度。这两个配置变量是用于英文分词的,要知道汉语词与词之间没有空格,所以如果使用ngram插件支持中文,ft_min_word_len和ft_max_word_len也会失效。这时你需要使用 ngram_token_size (默认值2,汉语词语一般是2个字,所以这个默认值是很合理的)来修改分词大小。配置完后重启mysql。你能使用 SHOW VARIABLES LIKE "ft_min_word_len" 查看配置有没有生效.

我这里配置是:

innodb_ft_min_token_size = 2
ngram_token_size = 2

如果没设置成功请确保:

  1. 确认my.conf正确配置,注意不要搞错my.conf的位置
  2. 确认mysql已经重启

到这里我们就配置完了。这些都应该是在创建索引之前配置,如果修改这些配置,之前已经创建的索引是不会生效的。这时候需要删掉索引,重新创建索引。

创建数据表

en 是英文分词的,cn使用了ngram插件,使之支持中文。

CREATE TABLE `my_ft` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `en` varchar(200) NULL COMMENT "英文",
  `cn` text NULL COMMENT "中文",
  PRIMARY KEY (`id`),
  FULLTEXT KEY `en` (`en`),
  FULLTEXT KEY `cn` (`cn`) with parser ngram
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

插入数据

mysql> INSERT INTO `my_ft` (`id`, `en`, `cn`) VALUES (1, 'I am 24 years old, I like white. My code is A.', 'MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。'), (2, 'You are 23 years old. Do you like white? Your code is AB.', 'Redis是一个开源的使用ANSI C语言编写、 支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API'), (3, 'Zhang is 14 years old. He likes blue. His code is ABC.', 'MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。'), (4, 'Wu is 35 years old. He likes red. His code is ABCD.', 'memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需 要频繁访问数据库的网站访问速度提升效果十分显著。'), (5, 'Li is 18 years old. He likes yellow. His code is ABCDE.', '数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。'), (6, 'Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.', 'SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。');
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

英文全文索引及innodb全文索引调试工具

mysql> SELECT *,MATCH(`en`) AGAINST('tom') as 'weight' FROM `my_ft` WHERE MATCH(`en`) AGAINST('tom')\G
*************************** 1. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.6055193543434143
1 row in set (0.00 sec)

看来没什么问题,能看到 tom 的权重是0.6055193543434143。这里还有注意,全文索引是不区分大小写的。因为我的 innodb_ft_min_token_size=2,所以所有2个及2个以上字母组成的单词都应该能查到。但是:

mysql> SELECT *,MATCH(`en`) AGAINST('is') as 'weight' FROM `my_ft` WHERE MATCH(`en`) AGAINST('is')\G
Empty set (0.00 sec)

很明显并不是这样,这时我想起来MyISAM的全文索引中,如果一个词在一列中出现的频率超过50%,他的权重就会降为0。MySQL认为这个词出现频率太高,不像是一个关键词。但是:

mysql> SELECT *,MATCH(`en`) AGAINST('old') as 'weight' FROM `my_ft` WHERE MATCH(`en`) AGAINST('old')\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 0.000000001885928302414186
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0.000000001885928302414186
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0.000000001885928302414186
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0.000000001885928302414186
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0.000000001885928302414186
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.000000001885928302414186
6 rows in set (0.00 sec)

可以看出来,“old”的权重已经很低了,但是并没有降为0。似乎innodb和MySQL这里并不一样。那为什么"is"就是不行呢?难道配置没生效?然后我有用“he”试了下,结果是能查到的。这是后我就迷糊了。后来又看了一些文献,才知道innodb还有个概念: stopword

mysql> SET GLOBAL innodb_ft_aux_table="test/my_ft";
Query OK, 0 rows affected (0.00 sec)

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)

这里可以看到,“is”已经被作为stopword,这才“is”权重被置为0的原因。你可以停止使用stopword,也可以自己配置stopword。这里先说怎么停止使用stopword。

mysql> SHOW VARIABLES LIKE "innodb_ft%";
+---------------------------------+------------+
| Variable_name                   | Value      |
+---------------------------------+------------+
| innodb_ft_aux_table             |            |
| innodb_ft_cache_size            | 8000000    |
| innodb_ft_enable_diag_print     | OFF        |
| innodb_ft_enable_stopword       | ON         |
| innodb_ft_max_token_size        | 84         |
| innodb_ft_min_token_size        | 2          |
| innodb_ft_num_word_optimize     | 2000       |
| innodb_ft_result_cache_limit    | 2000000000 |
| innodb_ft_server_stopword_table |            |
| innodb_ft_sort_pll_degree       | 2          |
| innodb_ft_total_cache_size      | 640000000  |
| innodb_ft_user_stopword_table   |            |
+---------------------------------+------------+
12 rows in set (0.00 sec)

可以看到 innodb_ft_enable_stopword  是开启状态,这时我以为在my.conf中配置为OFF( innodb_ft_enable_stopword=OFF )就可以了。配置文件修改需要重启mysql才能生效。生效只是针对后面修改或新增的数据,而且之前已有的数据索引,需要删掉索引,重新创建索引才行。但是:

mysql> SHOW VARIABLES LIKE "innodb_ft%";
+---------------------------------+------------+
| Variable_name                   | Value      |
+---------------------------------+------------+
| innodb_ft_aux_table             |            |
| innodb_ft_cache_size            | 8000000    |
| innodb_ft_enable_diag_print     | OFF        |
| innodb_ft_enable_stopword       | OFF        |
| innodb_ft_max_token_size        | 84         |
| innodb_ft_min_token_size        | 2          |
| innodb_ft_num_word_optimize     | 2000       |
| innodb_ft_result_cache_limit    | 2000000000 |
| innodb_ft_server_stopword_table |            |
| innodb_ft_sort_pll_degree       | 2          |
| innodb_ft_total_cache_size      | 640000000  |
| innodb_ft_user_stopword_table   |            |
+---------------------------------+------------+
12 rows in set (0.01 sec)

mysql> drop index `en` on my_ft;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table my_ft add fulltext `en`(`en`);
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SELECT *,MATCH(`en`) AGAINST('is') as 'weight' FROM `my_ft` WHERE MATCH(`en`) AGAINST('is')\G
Empty set (0.00 sec)

好吧,只能自己定义stopword表了。

mysql> CREATE TABLE `my_stopwords` (
    ->   `value` varchar(20) DEFAULT NULL
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.02 sec)

使用我自己的分词表,在这之前还要把配置改回来(注释掉 innodb_ft_enable_stopword=OFF )

mysql> SET GLOBAL innodb_ft_server_stopword_table = 'test/my_stopwords';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT *,MATCH(`en`) AGAINST('is') as 'weight' FROM `my_ft` WHERE MATCH(`en`) AGAINST('is')\G
*************************** 1. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0.000000003771856604828372
*************************** 2. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0.000000003771856604828372
*************************** 3. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0.000000003771856604828372
*************************** 4. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.000000003771856604828372
*************************** 5. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 0.000000001885928302414186
*************************** 6. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0.000000001885928302414186
6 rows in set (0.00 sec)

看看索引次的分布,先删掉“cn”字段的索引, 单独来看看“en”字段哪些词被加到索引中。

mysql> drop index `cn` on my_ft;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SET GLOBAL innodb_ft_aux_table="test/my_ft";
Query OK, 0 rows affected (0.00 sec)

mysql> select WORD, count(WORD) from information_schema.INNODB_FT_INDEX_TABLE group by WORD ;
+--------+-------------+
| WORD   | count(WORD) |
+--------+-------------+
| 14     |           1 |
| 18     |           1 |
| 20     |           1 |
| 23     |           1 |
| 24     |           1 |
| 35     |           1 |
| ab     |           1 |
| abc    |           1 |
| abcd   |           1 |
| abcde  |           1 |
| abcdef |           1 |
| am     |           1 |
| and    |           1 |
| are    |           1 |
| blue   |           1 |
| code   |           6 |
| do     |           1 |
| green  |           1 |
| he     |           5 |
| his    |           4 |
| is     |          10 |
| li     |           2 |
| like   |           2 |
| likes  |           4 |
| love   |           1 |
| my     |           1 |
| old    |           6 |
| red    |           1 |
| tom    |           1 |
| white  |           2 |
| wu     |           1 |
| years  |           6 |
| yellow |           1 |
| you    |           2 |
| your   |           1 |
| zhang  |           1 |
+--------+-------------+
36 rows in set (0.00 sec)

中文全文索引

重头戏来了,来看看中文全文索引。毕竟我们用全文索引也很少用于除中文外的其他语言。为了其他索引(en)的影响,我们先删掉索引“en”,再创建中文索引“cn”。

mysql> drop index `en` on my_ft;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> alter table my_ft add fulltext `cn`(`cn`) with parser ngram;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0
一、自然语言模式
mysql> SELECT *,MATCH(`cn`) AGAINST('mysql') as 'weight' FROM `my_ft` WHERE MATCH(`cn`) AGAINST('mysql')\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 3.332656145095825
*************************** 2. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.45528939366340637
2 rows in set (0.00 sec)

我本想查包含 “mysql” 的行,结果包含sql的行业被查了出来,这里我就有点方了。后来我试了下MyISAM引擎,发现只要使用ngram插件就会有这个问题。其实这个根本不是问题,一是有时候我们做搜索本来就需要将有关联的行全部查出来。这里mysql也是根据权重排序的,越匹配的行会被排在前面。二是我们可以用布尔模式避免这类事情的发生:

mysql> SELECT *,MATCH(`cn`) AGAINST('mysql' IN BOOLEAN MODE) as 'weight' FROM `my_ft` where MATCH(`cn`) AGAINST('mysql' IN BOOLEAN MODE)\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 3.332656145095825
1 row in set (0.00 sec)

再看看汉字索引是怎么分词的,这里只展示了 “MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。”这句话的索引结构

mysql> select WORD, count(WORD) from information_schema.INNODB_FT_INDEX_TABLE group by WORD ;
+--------+-------------+
| WORD   | count(WORD) |
+--------+-------------+
| ab     |           1 |
| ac     |           1 |
| cl     |           1 |
| le     |           1 |
| my     |           2 |
| or     |           1 |
| ql     |           2 |
| ra     |           1 |
| sq     |           2 |
| ys     |           2 |
| 一个   |           1 |
| 下产   |           1 |
| 个关   |           1 |
| 产品   |           1 |
| 公司   |           1 |
| 关系   |           1 |
| 典m    |           1 |
| 前属   |           1 |
| 发,   |           1 |
| 司开   |           1 |
| 品。   |           1 |
| 型数   |           1 |
| 属于   |           1 |
| 库管   |           1 |
| 开发   |           1 |
| 据库   |           1 |
| 数据   |           1 |
| 旗下   |           1 |
| 理系   |           1 |
| 瑞典   |           1 |
| 由瑞   |           1 |
| 目前   |           1 |
| 管理   |           1 |
| 系型   |           1 |
| 系统   |           1 |
| 统,   |           1 |
| ,由   |           1 |
| ,目   |           1 |

这里有的人执行 select WORD, count(WORD) from information_schema.INNODB_FT_INDEX_TABLE group by WORD; 却什么都查不到,执行之前一定要确保你执行过 SET GLOBAL innodb_ft_aux_table="test/my_ft"; 这个我上面是执行过得。为什么要执行这个,这其实是mysql提供的一个专门调试innodb全文索引的一个工具(我也不知道该不该叫根据),你可以看看下面两篇博客了解一下。

二、布尔模式

以上几乎查询都是在 自然语言模式 下,下面我们来试试 布尔模式 ,这也是我们常用的模式。

mysql> SELECT *,MATCH(`cn`) AGAINST('数据库' IN BOOLEAN MODE) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 0.000000003771856604828372
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0.000000003771856604828372
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0.000000005657784907242558
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0.000000003771856604828372
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0.000000005657784907242558
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.00000000942964106798172
6 rows in set (0.00 sec)

如果作为where条件,weight为0的行就被忽略了。这里权重非常低应该是因为“数据库”这个词出现频率太高了。

多个检索词时,匹配更多检索词的行,权重更高:

mysql> SELECT *,MATCH(`cn`) AGAINST('数据库 Oracle' IN BOOLEAN MODE) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 2.2718474864959717
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0.000000003771856604828372
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0.000000005657784907242558
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0.000000003771856604828372
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0.000000005657784907242558
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.00000000942964106798172
6 rows in set (0.01 sec)

加号(+)表示一定要存在该词:

mysql> SELECT *,MATCH(`cn`) AGAINST('数据库 +Oracle' IN BOOLEAN MODE) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 2.2718474864959717
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0
6 rows in set (0.00 sec)

减号(-)表示一定不能存在该词:

mysql> SELECT *,MATCH(`cn`) AGAINST('数据库 -Oracle' IN BOOLEAN MODE) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 0
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0.000000003771856604828372
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0.000000005657784907242558
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0.000000003771856604828372
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0.000000005657784907242558
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.00000000942964106798172
6 rows in set (0.00 sec)

大于号(>)提高该词的权重(这里应该跟 “数据库 Oracle”作对比):

mysql> SELECT *,MATCH(`cn`) AGAINST('数据库 >Oracle' IN BOOLEAN MODE) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 3.2718472480773926
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0.000000003771856604828372
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0.000000005657784907242558
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0.000000003771856604828372
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0.000000005657784907242558
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.00000000942964106798172
6 rows in set (0.00 sec)

小于号(<)降低该词的权重(这里应该跟 “数据库 Oracle”作对比):

mysql> SELECT *,MATCH(`cn`) AGAINST('数据库 <Oracle' IN BOOLEAN MODE) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 1.2718474864959717
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0.000000003771856604828372
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0.000000005657784907242558
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0.000000003771856604828372
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0.000000005657784907242558
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.00000000942964106798172
6 rows in set (0.00 sec)

波浪号(~)表示负相关。但是从上面可以看到“数据库”这个词权重是:0.000000003771856604828372,“Oracle”权重大约是2.27,按理说使用 “~” 权重应该是0.000000003771856604828372减2.27,权重为负,当然权重最低是0.但是结果并不是这样。感觉“~”变得和“>”一样了,只是降低权重。当然可能是我对“~”理解是错的,后面再研究。

mysql> SELECT *,MATCH(`cn`) AGAINST('数据库 ~Oracle' IN BOOLEAN MODE) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 1.2718474864959717
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0.000000003771856604828372
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0.000000005657784907242558
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0.000000003771856604828372
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0.000000005657784907242558
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.00000000942964106798172
6 rows in set (0.00 sec)

星号(*)模糊匹配(这里应该跟 “数据库” 作对比):

mysql> SELECT *,MATCH(`cn`) AGAINST('数据库 开*' IN BOOLEAN MODE) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 0.09061906486749649
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0.09061906486749649
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0.000000005657784907242558
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0.09061906486749649
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0.000000005657784907242558
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.00000000942964106798172
6 rows in set (0.00 sec)

双引号("")表示引号内词语不可拆分,顺序不可调换。:

mysql> SELECT *,MATCH(`cn`) AGAINST('"数据库 Oracle"' IN BOOLEAN MODE) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 0
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0
6 rows in set (0.00 sec)

括号(())用来将单词分成子表达式,括入括号的部分可以被嵌套。然而我并不知道怎么用:

timg (3).jpeg

三、查询扩展模式

我们最后再来试试 查询扩展模式 ,我们先加一行数据:

mysql> INSERT INTO `my_ft` (`en`, `cn`) VALUES ( 'Add test data.', '程序 这个词只在第六行中出现过。');
Query OK, 1 row affected (0.01 sec)

我们查“瑞典”这个词,其实只有第一行数据中带有这个词,但是结果1-6行数据都有权重。这是因为,2-6行中或多或少有些词在第一行中也出现过。扩展模式认为这些可能也是你想查询的数据。

mysql> SELECT *,MATCH(`cn`) AGAINST('瑞典' WITH QUERY EXPANSION) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 21.56450080871582
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0.1443706452846527
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0.14885252714157104
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 2.2164409160614014
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0.013445617631077766
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 1.3418564796447754
*************************** 7. row ***************************
    id: 7
    en: Add test data.
    cn: 程序 这个词只在第六行中出现过。
weight: 0
7 rows in set (0.01 sec)

再看下面这个实例,可能更好理解。

mysql> SELECT *,MATCH(`cn`) AGAINST('六行' WITH QUERY EXPANSION) as 'weight' FROM `my_ft`\G
*************************** 1. row ***************************
    id: 1
    en: I am 24 years old, I like white. My code is A.
    cn: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。
weight: 0
*************************** 2. row ***************************
    id: 2
    en: You are 23 years old. Do you like white? Your code is AB.
    cn: Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
weight: 0
*************************** 3. row ***************************
    id: 3
    en: Zhang is 14 years old. He likes blue. His code is ABC.
    cn: MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
weight: 0
*************************** 4. row ***************************
    id: 4
    en: Wu is 35 years old. He likes red. His code is ABCD.
    cn: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。
weight: 0
*************************** 5. row ***************************
    id: 5
    en: Li is 18 years old. He likes yellow. His code is ABCDE.
    cn: 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。
weight: 0
*************************** 6. row ***************************
    id: 6
    en: Tom is 20 years old. He likes green, and he love Li. His code is ABCDEF.
    cn: SQL是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
weight: 0.13540691137313843
*************************** 7. row ***************************
    id: 7
    en: Add test data.
    cn: 程序 这个词只在第六行中出现过。
weight: 2.9178578853607178
7 rows in set (0.00 sec)

热门文章