MySQL 全文检索的使用示例

1. 环境准备

MySQL 5.7.6之前,全文索引只支持英文全文索引,不支持中文全文索引,需要利用分词器把中文段落预处理拆分成单词,然后存入数据库。 MySQL 5.7.6开始,MySQL内置了ngram全文解析器,用来支持中文、日文、韩文分词。 本文使用的MySQL 版本是5.7.22,InnoDB数据库引擎。

所以这里需要MySQL的版本大于5.7.6

-- 查看mysql的版本
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.33    |
+-----------+
1 row in set (0.02 sec)

在 mysql 配置文件中添加分词以及最小词语长度 (如果已经配置可以忽略)

ft_min_word_len 最小字符长度默认为 4,在英文条件下确实比较合理中文情况下需要修改;

ngram_token_size 分词的最小长度 举个例子 不同长度对 你好世界 的分词

n=1: '你', '好', '世', '界'
n=2: '你好', '好世', '世界'
n=3: '你好世', '好世界'
n=4: '你好世界'
# /etc/mysql/mysql.conf.d/mysqld.cnf

ft_min_word_len = 2
ngram_token_size = 2

# 如果没有则新增配置
echo 'ft_min_word_len = 2
ngram_token_size = 2' >> mysqld.cnf

# 重启服务
/etc/init.d/mysql restart
-- 查看配置
mysql>
SHOW VARIABLES LIKE 'ft_min_word_len';
SHOW VARIABLES LIKE 'ngram_token_size';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| ft_min_word_len | 2     |
+-----------------+-------+
1 row in set (0.02 sec)

+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| ngram_token_size | 2     |
+------------------+-------+
1 row in set (0.03 sec)

2. 数据准备

-- mysql 于全文检索的demo

mysql> CREATE TABLE `articles` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(50) DEFAULT NULL COMMENT '主题',
  `content` longtext NOT NULL COMMENT '内容',
  PRIMARY KEY (`id`),
  FULLTEXT KEY `title_content_index` (`content`,`title`) /*!50100 WITH PARSER `ngram` */
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.20 sec)

mysql> INSERT INTO articles (`title`, `content`) VALUES
        ('如果','今生今世 永不再将你想起
除了
除了在有些个
因落泪而湿润的夜里 如果
如果你愿意'),
        ('爱情','有一天路标迁了希望你能从容
有一天桥墩断了希望你能渡越
有一天栋梁倒了希望你能坚强
有一天期待蔫了希望你能理解'),
        ('远和近','你 一会看我
一会看云
我觉得
你看我时很远
你看云时很近'),
        ('断章','你站在桥上看风景,
看风景人在楼上看你。
明月装饰了你的窗子,
你装饰了别人的梦。'),
        ('独语','我向你倾吐思念
你如石像
沉默不应
如果沉默是你的悲抑
你知道这悲抑
最伤我心');

Query OK, 5 rows affected (0.08 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> SELECT * from articles where match(content, title) against('风景' in  NATURAL LANGUAGE MODE) LIMIT 10;
+----+--------+--------------------------------------------------------------------------------------------------------------------------+
| id | title  | content                                                                                                                  |
+----+--------+--------------------------------------------------------------------------------------------------------------------------+
| 10 | 断章 |  你站在桥上看风景,
看风景人在楼上看你。
明月装饰了你的窗子,
你装饰了别人的梦。 |
+----+--------+--------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.02 sec)

3. 开始表演

  • 自然语言模式(NATURAL LANGUAGE MODE)

自然语言模式是MySQL 默认的全文检索模式。自然语言模式不能使用操作符,不能指定关键词必须出现或者必须不能出现等复杂查询。

  • 布隆模式(BOOLEAN MODE)

BOOLEAN模式可以使用操作符,可以支持指定关键词必须出现或者必须不能出现或者关键词的权重高还是低等复杂查询。

  • 查询扩展(QUERY EXPANSION)

查询的结果不仅匹配出结果同时可以联想出其他你需要的结果。(类似关联查询,但是官网推荐仅支持短语查询 否则会出现很多脏数据)

-- 自然语言模式(NATURAL LANGUAGE MODE)查询并得到评分

mysql> SELECT id, title, MATCH ( content, title ) against ( '风景' IN NATURAL LANGUAGE MODE ) AS score  FROM articles;
+----+-----------+--------------------+
| id | title     | score              |
+----+-----------+--------------------+
|  7 | 如果    |                  0 |
|  8 | 爱情    |                  0 |
|  9 | 远和近 |                  0 |
| 10 | 断章    | 0.9771181344985962 |
| 11 | 独语    |                  0 |
+----+-----------+--------------------+
5 rows in set (0.02 sec)

-- 布隆模式(BOOLEAN MODE) 可以组合查询

mysql> SELECT id, title  FROM articles where MATCH ( content, title ) against ( '+风景 -爱情' IN BOOLEAN MODE );
+----+--------+
| id | title  |
+----+--------+
| 10 | 断章 |
+----+--------+
1 row in set (0.01 sec)

-- 查询扩展(QUERY EXPANSION) 可以联想出其他结果
mysql> SELECT id, title  FROM articles where MATCH ( content, title ) against ( '风景' WITH QUERY EXPANSION );
+----+--------+
| id | title  |
+----+--------+
| 10 | 断章 |
| 11 | 独语 |
+----+--------+
2 rows in set (0.02 sec)

4. 分词引擎

目前官网 MeCab Full-Text Parser 有支持日语的分词插件(可以更好的理解语义)

内置的 full-text parser 因为英文中单词的边界默认是空格,所以在处理英文文本时可以简单的使用空格作为分隔符。但是在处理中文时需要理解语义的基础上进行有效的分词,所以在处理中文、日文、韩文MySQL 提供了 ngram full-text (本文的配置就是 基于ngram的中文分词)

总结

优点

  • 对比 like 查询效率有提升(具体提升的测试没有做)
  • 全文搜索可以同时对多个字段做索引,like只能对单一字段搜索

对于中文的分词可能需要在理解语义的基础上才能有效的分词;比如上文中的 你好世界(hello world)对于英文按空格切分就可以,中文则需要理解语义的基础才能分成 你好/世界。

这里分享一下python中jieba分词,有助于理解中文分词的魅力

结巴分词利用一个中文词库,通过词库计算汉字之间构成词语的关联概率,所以通过计算汉字之间的概率,就可以形成分词的结果。

In [1]: import jieba

In [2]: jieba.lcut("你好世界")
Building prefix dict from the default dictionary ...
Dumping model to file cache /var/folders/st/b16fyn3s57x_5vszjl599njw0000gn/T/jieba.cache
Loading model cost 0.937 seconds.
Prefix dict has been built successfully.
Out[2]: ['你好', '世界']

In [3]: jieba.lcut("hello world")
Out[3]: ['hello', ' ', 'world']

对于一般的项目mysql的全文索引可以解决80%的需求,它可以较为完美的支持中文的检索、自动分词、结果排序、组合查询等功能;但性能应该是瓶颈,Elastissearch可以友好的实现全文检索。

全文索引不能达到like的效果,连着的语句会因为分词形成多个词语。

参考资料

Mysql fulltext

以上就是MySQL 全文检索的使用示例的详细内容,更多关于MySQL 全文检索的使用的资料请关注我们其它相关文章!

(0)

相关推荐

  • Mysql实现全文检索、关键词跑分的方法实例

    一.前言 今天一个同事问我,如何使用 Mysql 实现类似于 ElasticSearch 的全文检索功能,并且对检索关键词跑分?我当时脑子里立马产生了疑问?为啥不直接用es呢?简单好用还贼快.但是听他说,数据量不多,客户给的时间非常有限,根本没时间去搭建es,所以还是看一下 Mysql 的全文检索功能吧! MySQL 从 5.7.6 版本开始,MySQL就内置了ngram全文解析器,用来支持中文.日文.韩文分词.在 MySQL 5.7.6 版本之前,全文索引只支持英文全文索引,不支持中文全文索引

  • PHP+MySQL+sphinx+scws实现全文检索功能详解

    本文实例讲述了PHP+MySQL+sphinx+scws实现全文检索功能.分享给大家供大家参考,具体如下: 我的个人环境是PHP7.1+MariaDB10.1.23 下载安装资源包 sphinx地址 http://sphinxsearch.com/downloads/release/ PHP的sphinx扩展下载 http://pecl.php.net/package/sphinx SCWS 下载地址 http://www.xunsearch.com/scws/download.php SCWS

  • mysql 全文检索中文解决方法及实例代码

    mysql 全文检索中文解决方法             最近公司项目要求这样的功能,在数据库中检索中文,很是棘手,上网查询下资料,找的类似文章,这里及记录下,希望能帮助到大家, 实例代码:    <?php /* mysql全文检索中文解决方案! */ error_reporting(E_ERROR | E_WARNING | E_PARSE); ini_set('display_errors', '1'); //数据库支持 class SaeMysql{ //phpmysql操作类 } $D

  • 深度解析MySQL 5.7之中文全文检索

    前言 其实全文检索在MySQL里面很早就支持了,只不过一直以来只支持英文.缘由是他从来都使用空格来作为分词的分隔符,而对于中文来讲,显然用空格就不合适,需要针对中文语义进行分词.这不,从MySQL 5.7开始,MySQL内置了ngram全文检索插件,用来支持中文分词,并且对MyISAM和InnoDB引擎有效. 在使用中文检索分词插件ngram之前,先得在MySQL配置文件里面设置他的分词大小,比如, [mysqld] ngram_token_size=2 这里把分词大小设置为2.要记住,分词的S

  • MySQL 全文检索的使用示例

    1. 环境准备 MySQL 5.7.6之前,全文索引只支持英文全文索引,不支持中文全文索引,需要利用分词器把中文段落预处理拆分成单词,然后存入数据库. MySQL 5.7.6开始,MySQL内置了ngram全文解析器,用来支持中文.日文.韩文分词. 本文使用的MySQL 版本是5.7.22,InnoDB数据库引擎. 所以这里需要MySQL的版本大于5.7.6 -- 查看mysql的版本 mysql> select version(); +-----------+ | version() | +-

  • Python操作ES的方式及与Mysql数据同步过程示例

    目录 Python操作Elasticsearch的两种方式 mysql和Elasticsearch同步数据 haystack的使用 Redis补充 Python操作Elasticsearch的两种方式 # 官方提供的:Elasticsearch # pip install elasticsearch # GUI:pyhon能做图形化界面编程吗? -Tkinter -pyqt # 使用(查询是重点) # pip3 install elasticsearch https://github.com/e

  • springboot微服务Lucence实现Mysql全文检索功能

    目录 一.前言 1.1 常规调优手段 1.1.1 加索引 1.1.2 代码层优化 1.1.3 减少关联表查询 1.1.4 分库分表 1.1.5 引入第三方存储 二.一个棘手的问题 2.1 前置准备 2.1.1 创建一张表 2.1.2 插入一些数据 2.2 问题引发 2.2.1 关键字模糊查询 2.2.2 执行计划分析 2.2.3 需求引出 三.lucence与全文检索 3.1 Lucene概念 3.2 全文检索 3.3 Lucene 建立索引的过程 四.基于Lucence解决方案 4.1 需求分

  • mysql 行列转换的示例代码

    一.需求 我们有三张表,我们需要分类统计一段时间内抗生素的不同药敏结果,即 report_item_drugs 表的 drugs_result, 在不同项目project_name 和不同抗生素 antibiotic_dict_name 下的占比,并将药敏结果显示在行上,效果如下: 三张原始表(仅取需要的字段示例),分别是: 报告表 项目表 抗生素表(药敏结果drugs_result为一列值) 二.实现 1.按照项目.抗生素分组求出检出的总数 SELECT A.project_name,A.an

  • python3 实现mysql数据库连接池的示例代码

    dbutils封装文件传送门 DBUtils是一套Python数据库连接池包,并允许对非线程安全的数据库接口进行线程安全包装.DBUtils来自Webware for Python. DBUtils提供两种外部接口: PersistentDB :提供线程专用的数据库连接,并自动管理连接. PooledDB :提供线程间可共享的数据库连接,并自动管理连接. 需要库 1.DBUtils pip install DBUtils 2.pymysql pip install pymysql/MySQLdb

  • Python3 MySQL 数据库连接的使用示例

    目录 什么是 PyMySQL? PyMySQL 安装 数据库连接 实例: 创建数据库表 数据库插入操作 数据库查询操作 数据库更新操作 删除操作 执行事务 错误处理 本文我们为大家介绍 Python3 使用 PyMySQL 连接数据库,并实现简单的增删改查. 什么是 PyMySQL? PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb. PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-

  • MySQL数据库事务transaction示例讲解教程

    目录 1.什么是事务? 2.和事务相关的语句只有这3个DML语句:insert.delete.update 3.假设所有的业务都能使用1条DML语句搞定,还需要事务机制吗? 4.事务的原理 5.事务的四大特性:ACID 6.关于事务之间的隔离性 1)第一级别:读未提交(read uncommitted) 2)第二级别:读已提交(read committed) 3)第三级别:可重复读(repeatable read) 4)第四级别:序列化读/串行化读(serializable) 7.演示事务的隔离

  • MySQL数据分析存储引擎示例讲解

    目录 1.引入案例 2.查看系统默认的存储引擎和默认字符集 3.常见的存储引擎 1)MyISAM:不支持事务.(张马虎) MyISAM的优缺点: 2)InnoDB:支持事务.(李小心) InnoDB的优缺点: 3)MEMORY(这个了解一下就行了) MEMORY的优缺点: 4.下面这张图了解就行 今天我们来说说MySQL存储引擎,作为从事数据分析行业的朋友老说,我们不必细究MySQL存储引擎到底什么,我们了解就行了. 1.引入案例 有张马虎.李小心两个人,都是地铁口的自行车管理员,每天都有很多人

  • python 实现mysql增删查改示例代码

    本地安装配置phpstduy 安装这个数据库管理工具 一会我们要手动创建数据库 数据表 字段 当然也可以代码创建 1.增 import pymysql ''' host 主机名 这里是你的ip地址 user 数据库账号 password 数据库密码 port 端口 mysql数据库端口 db 数据库名 基本语句 cursor = conn.cursor()#初始化一个游标对象 sql = "数据库操作语句" cursor.execute(sql)#执行该语句 conn.commit()

随机推荐