全文索引是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。
从MySQL5.6版本开始支持InnoDB引擎的全文索引,语法层面上大多数兼容之前MyISAM的全文索引模式。5.7版本之后通过使用ngram插件开始支持中文。之前仅支持英文,因为是通过空格作为分词的分隔符,对于中文来说是不合适的。MySQL允许在char、varchar、text类型上建立全文索引。
MySQL支持三种模式的全文检索模式:
1、自然语言模式(IN NATURAL LANGUAGE MODE)默认模式。
2、布尔模式(IN BOOLEAN MODE),可以为检索的字符串增加操作符,例如“+”表示必须包含,“-”表示不包含,“*”表示通配符(这种情况, 即使传递的字符串较小或出现在停词中,也不会被过滤掉),其他还有很多特殊的布尔操作符,可以通过如下参数控制:
- +word: >一定要有(不含有该关键词的数据条均被忽略)。
- -word: 不可以有(排除指定关键词,含有该关键词的均被忽略)。
- >word: 提高该条匹配数据的权重值。
- <word: 降低该条匹配数据的权重值。
- ~word: 将其相关性由正转负,表示拥有该字会降低相关性(但不像 - 将之排除),只是排在较后面权重值降低。
- "word1 word2": 用双引号将一段句子包起来表示要完全相符,不可拆字。[给定单词必须出现在数据记录中,先后顺序也必须匹配,区分字母大小写]
- word*: 搜索以word开头的单词,只允许出现在单词的末尾
- (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
如果没设置成功请确保:
- 确认my.conf正确配置,注意不要搞错my.conf的位置
- 确认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)
括号(())用来将单词分成子表达式,括入括号的部分可以被嵌套。然而我并不知道怎么用:
三、查询扩展模式
我们最后再来试试 查询扩展模式 ,我们先加一行数据:
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)