MySql 全文索引

MySql 全文索引

    • 1.MySql 全文索引介绍
    • 2.ngram 简介
    • 3.数据库配置
    • 4.创建全文索引
    • 5.使用全文索引
      • 布尔模式
        • 校验 ngram
      • 自然语言模式
      • 拓展查询
    • 6.相关性排序
    • 7.注意事项

1.MySql 全文索引介绍

Mysql 的全文索引主要用于全文字段的检索场景,支持 char、varchar、text 几个字段加全文索引,仅支持 InNoDB 与 MyISAM 引擎。

MySql 内置了 ngram 解析器来支持中文、日文、韩文等语言的文本,全文索引支持通过建表来创建或建表后新增。

全文索引支持三种模式:

  • 布尔模式(Boolean Full-Text Searches)
  • 自然语言模式(Natural Language Full-Text Searches)
  • 查询拓展(Full-Text Searches with Query Expansion)

2.ngram 简介

ngram 一种基于统计语言模型的算法,简单来说,就是通过一个大小为 n 的滑动窗口,将一段文本分成多个由 n 个连续单元组成的 term。例:

n = 2
text = 湖北省武汉市

经过 ngram 解析器解析后,得到如下分词:

湖北 北省 省武 武汉 汉市

ngram 全文解析器是 MySql 服务内置的插件,与其他插件一样,在 MySql 服务启动的时候会自动加载。

参考:
https://zhuanlan.zhihu.com/p/32829048《自然语言处理中N-Gram模型介绍》
https://dev.mysql.com/doc/refman/5.7/en/fulltext-search-ngram.html《ngram Full-Text Parser》

3.数据库配置

  • 先看 MySql 版本
    ngram 解析器是 mysql5.7 版本后,内置的全文搜索解析器,所以要求 mysql 版本要在5.7及以上
    查看 mysql 版本:
    select version()
    
  • 配置 ngram
    ngram 可以作为启动字符串的一部分或者在配置文件中设置
    启动字符串:
    -- 中文分词长度位2,每个字都可以查出来
    mysqld --ngram_token_size=2
    
    配置文件(my.ini):
    以 windows 系统为例,首先找到 my.ini 文件(默认安装路径:C:\ProgramData\MySQL\MySQL Server 5.7\my.ini),编辑该文件,在文件后加上:ngram_token_size=2,配置完成后重启服务。

4.创建全文索引

  • 通过建表语句创建
    CREATE TABLE `news`  (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
      `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '内容',
      `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标题',
      PRIMARY KEY (`id`) USING BTREE,
      FULLTEXT INDEX `idx_full_text`(`content`) WITH PARSER `ngram`
    ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
    
  • 通过 CREATE FULLTEXT INDEX 语句创建
    CREATE FULLTEXT INDEX idx_full_text ON news (content) WITH PARSER ngram;
    

5.使用全文索引

首先写入部分测试数据:

INSERT INTO `news` VALUES (1, '武汉市今天有小雨,大家出门记得带雨伞', '武汉天气');
INSERT INTO `news` VALUES (2, '湖北省武汉市是中部最大的城市,华中地区第一大都市', '湖北省武汉市');
INSERT INTO `news` VALUES (3, '武汉大学今年不开放樱花观赏,请各位游客不必前往', '武大樱花');
INSERT INTO `news` VALUES (4, '湖北省是千湖之省,风景秀丽,欢迎全国各地游客', '湖北省旅游');
INSERT INTO `news` VALUES (5, '武汉光谷是武汉市高新技术公司聚集地,大量来自全球各地的优秀人才聚集在此', '武汉光谷');

布尔模式

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

操作符含义
无操作符出现了,相关性会更高
+必须包含
-必须不包含
@distance需要满足一定的编辑距离 仅仅支持InnoDB存储引擎
<降低相关性
>增加相关性
~负相关性,如果包含,相关性会比不包含更低
*与 like 类似,放在字段前或后
“”将引号内的内容当整体检索

下面分别介绍几种操作符的用法:

select * from news where MATCH (content) against ('武汉 雨伞' in Boolean MODE); 

在这里插入图片描述无操作符则表示出现’武汉’或者’雨伞’的数据会有更高的相关性。

select * from news where MATCH (content) against ('+武汉' in Boolean MODE);

在这里插入图片描述
+武汉表示必须出现’武汉’这个单词数据才能被检索到,从结果可以看出,'武汉’这个单词出现次数最多的排在最前面(参考第7章节)。

select * from news where MATCH (content) against ('+武汉 -雨伞' in Boolean MODE); 

在这里插入图片描述
+武汉表示被检索到的数据必须包含’武汉’这个分词,-雨伞表示被检索到的数据必须不能包含’雨伞这个分词’。

select * from news where MATCH (content) against ('+武汉 <雨伞' in Boolean MODE); 

在这里插入图片描述'武汉 <雨伞’表示需要检索到包含武汉的数据,但是当出现’雨伞’这个分词时,需要降低相关性,所以带有’雨伞’的数据会排在最后。

select * from news where MATCH (content) against ('"全球 优秀"@5' in Boolean MODE);

这个@distance语法不知道为啥一直没有查出结果(待查明原因)

select * from news where MATCH (content) against ('武汉  ~雨伞' in Boolean MODE);

在这里插入图片描述
'武汉 ~雨伞’表示需要检索到包含武汉的数据,但是当出现’雨伞’这个分词时,相关性为负,所以带有’雨伞’的数据会排在最后(这个效果与<操作符有类似效果)。

select * from news where MATCH (content) against ('全球*' in Boolean MODE);

在这里插入图片描述
*操作符的作用其实与like的通配符类似。

select * from news where MATCH (content) against ('"武汉光谷"' in Boolean MODE);

在这里插入图片描述
双引号表示’武汉光谷’以短语的方式被检索到。

校验 ngram

前面讲到了 ngram 分词,下面校验一下 ngram 分词:
在这里插入图片描述
以数据表的第一条文本为例:

select * from news where MATCH (content) against ('天有' in Boolean MODE);

在这里插入图片描述
检索’天有’这个分词能够检索出’武汉市今天有小雨,大家出门记得带雨伞’这条文本,说明这条文本的分词情况如下:

武汉 汉市 市今 今天 天有 有小 小雨 。。。

说明 ngram(n=2) 解析器将文本分成了以2为滑动窗口,将一段文本分成多个由2个连续单元组成的 term。

自然语言模式

自然语言模式是默认全文检索模式,简单来说就是把检索关键词当作自然语言来处理,自然语言模式也等价于布尔模式中的无操作符,下面三种查询,结果是一样的:

-- 自然语言模式
select * from news where MATCH (content) against ('技术 武汉 光谷' IN NATURAL LANGUAGE MODE);
-- 布尔模式 无操作符
select * from news where MATCH (content) against ('技术 武汉 光谷' in Boolean MODE);
-- 默认模式
select * from news where MATCH (content) against ('技术 武汉 光谷');

在这里插入图片描述
这三种查询结果和排序都是一样的

拓展查询

拓展查询模式会进行两次查询,第一次查询命中关键词,第二次查询会根据第一次查询到的结果作为输入,再进行一次查询。
首先,我们 doc 列表如下:
在这里插入图片描述
先查询关键词 ‘西湖’:

select * from news where MATCH (content) against ('西湖' WITH QUERY EXPANSION);

在这里插入图片描述
上面通过 WITH QUERY EXPANSION 查询 ‘西湖’ 就返回一条与其相关的数据
下面再插入一条数据:
在这里插入图片描述
再来拓展查询 ‘西湖’:

select * from news where MATCH (content) against ('西湖' WITH QUERY EXPANSION);

在这里插入图片描述
再看结果,发现多了一条与 ‘西湖’ 无关的记录(就是刚刚新增的数据)。

那么为什么会出现这样的结果呢?
原因是拓展查询会根据第一次查询到的结果再进行一次查询,第一次查询到的结果是关于 ‘西湖’ 的结果,结果理包含了 ‘杭州’、 ‘美丽’、 ‘地方’ 等关键词,第二次查询会检索 ‘杭州’、 ‘美丽’、 ‘地方’ 等关键词,所以自然会查询到上面两条数据,下面再新增几条数据来验证:
在这里插入图片描述
上面新增数据11和12。再次拓展查询’西湖’:

select * from news where MATCH (content) against ('西湖' WITH QUERY EXPANSION);

在这里插入图片描述
查询结果包括刚刚新增的11、12两条数据(因为这两条数据包括’西湖’关键字的第一次查询结果里面的关键词)。
上面的拓展查询结果相当于下面这两次查询:

-- 首先根据'西湖'关键词 查询出 '杭州'、'美丽'、'地方' 等结果
select content from news where MATCH (content) against ('西湖' IN NATURAL LANGUAGE MODE)
-- 再根据 '杭州'、'美丽'、'地方' 等结果二次查询
select * from news where MATCH (content) against ('杭州 美丽 地方' IN NATURAL LANGUAGE MODE)

拓展查询很有可能查询出很多意想不到的结果,有点盲查的意思。

6.相关性排序

InNoDB 的全文搜索基于 Sphinx 搜索引擎,相关性排序算法采用的是 BM25 and TF-IDT,熟悉 ES 的同学应该对 TF-IDT 不陌生,TF-IDT 简单来说就是:被检索关键词出现越多的 doc 相关性越高,包含高辨识度(整体上在 doc 里面出现的比较少)关键词的 doc 相关性越高,相关性越高,就越会被排在结果的前面。

SELECT
	*,
	MATCH ( content ) against ( '武汉 杭州' IN Boolean MODE ) AS score 
FROM
	news 
ORDER BY
	score DESC;

在这里插入图片描述
上面检索了’武汉’、‘杭州’两个关键词,从结果中可以看出:

  • 出现’杭州’(因为’杭州’整体上出现的较少,所以辨识度较高 IDF)的记录(doc)得分较高(相关性交大),排在前面
  • 武汉出现较多的记录得分也比较高(TF)

7.注意事项

  • 只能在类型为 char、varchar 或者 text 的字段上创建全文索引
  • 全文索引只支持 InnoDB 和 MyISAM 引擎
  • MATCH (columnName) AGAINST (‘keywords’)。MATCH() 函数使用的字段名,必须要与创建全文索引时指定的字段名一致。如上面的示例,MATCH ( title,body) 使用的字段名与全文索引 ft_articles(title,body) 定义的字段名一致。如果要对 title 或者 body 字段分别进行查询,就需要在 title 和 body 字段上分别创建新的全文索引
  • MATCH() 函数使用的字段名只能是同一个表的字段,因为全文索引不能够跨多个表进行检索
  • 如果不是英文单词,是字符串,用串中子字符串查不到(同分词长度有一定关系);但如果串中是用空格、‘,’,‘,’,';'等符号隔开,则可以查询
  • 如果一个字段中英文混合,用英文模式建,默认单词长度位4。查中文要求:查询内容3个字或以上,且是单独句型,前后用语法分隔符分隔的;用中文模式建,英文查找慢,且结果不正确,匹配项大量增加
  • 多字段共建成一个全文索引,则存储少,但查询速度慢
  • 多字段共建成一个全文索引,如果中英文混合,按英文模式建,中文(查询内容3个字或以上,且是单独句型,前后用语法分隔符分隔的);按中文模式建,中文查找模式准确,也快,但英文查找慢且匹配项大量增加
  • 表设计建议:1 一个表最好只有一个全文索引字段、2 字段内容最好是全英文或全中文

好事定律:每件事最后都会是好事,如果不是好事,说明还没到最后。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/870397.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

博客建站4 - ssh远程连接服务器

1. 什么是SSH?2. 下载shh客户端3. 配置ssh密钥4. 连接服务器5. 常见问题 5.1. IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! 1. 什么是SSH? SSH&#xff08;Secure Shell&#xff09;是一种加密的网络协议&#xff0c;用于在不安全的网络中安全地远程登录到其他…

浪潮自研交换机系列常见问题处理

CN61108PC-V-H 不能PING通任何地址&#xff0c;也不能被PING 输入ip traceroute enable既可。注意视图 交换机通过console口远程登录至其他交换机&#xff0c;掉线后console口无法使用 例如有2台交换机A和B&#xff0c;在A交换机上插上console线登录后&#xff0c;在A通过SSH…

linux、windows、macos,命令终端清屏

文章目录 LinuxWindowsmacOS 在Linux、Windows和macOS的命令终端中&#xff0c;清屏的命令或方法各不相同。以下是针对这三种系统的清屏方法&#xff1a; Linux clear命令&#xff1a;这是最常用的清空终端屏幕的命令之一。在终端中输入clear命令后&#xff0c;屏幕上的所有内容…

H5+CSS+JS工作性价比计算器

工作性价比&#xff1d;平均日新x综合环境系数/35 x(工作时长&#xff0b;通勤时长—0.5 x摸鱼时长) x学历系数 如果代码中的公式不对&#xff0c;请指正 效果图 源代码 <!DOCTYPE html> <html> <head> <style> .calculator { width: 300px; padd…

前端JS特效第56集:基于canvas的粒子文字动画特效

基于canvas的粒子文字动画特效&#xff0c;先来看看效果&#xff1a; 部分核心的代码如下(全部代码在文章末尾)&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compat…

【C语言】 约瑟夫环,循环链表实现

更新一下&#xff0c;昨天的代码有点问题&#xff0c;没有考虑到头结点的影响&#xff0c;我的方法是&#xff1a; 在进行步数位移的时候判断标记点&#xff0c;如果走到了头结点&#xff0c;就在循环里面立即往后再位移一次&#xff0c;把头结点跳过&#xff1b;同时在后面删除…

20分钟上手新版Skywalking 9.x APM监控系统

Skywalking https://skywalking.apache.org/ Skywalking是专为微服务、云原生和基于容器的&#xff08;Kubernetes&#xff09;架构设计的分布式系统性能监控工具。 Skywalking关键特性 ● 分布式跟踪 ○ 端到端分布式跟踪。服务拓扑分析、以服务为中心的可观察性和API仪表板。…

2024国际燃气轮机运维周线上分享第一期开启!共探燃机新生态

为促进国内重型燃气轮机运维技术发展&#xff0c;加快建立独立自主的燃气轮机运维技术体系&#xff0c;2024国际燃气轮机运维大会将于2024年10月17-18日在中国广州盛大召开&#xff01; 2024国际燃气轮机运维大会将通过线上直播会议、线下技术分享及颁奖典礼等形式展开&#xf…

spine to unity-2.利用边缘框实现实时碰撞检测

主要讲spine的边缘框&#xff0c;在unity中&#xff0c;实现实时碰撞检测。其中使用的素材&#xff0c;是我为独立游戏ink制作的动画。独立游戏ink的开发日志&#xff0c;在小红薯持续更新中。spine工具包的安装&#xff0c;下载请参考spine to unity-1spine BoundingBoxFollow…

Vue 实现电子签名并生成签名图片

目录 前言项目结构代码实现 安装依赖创建签名画布组件生成签名图片 总结相关阅读 1. 前言 电子签名在现代Web应用中越来越普遍&#xff0c;例如合同签署、确认表单等。本文将介绍如何使用Vue.js实现一个简单的电子签名功能&#xff0c;并将签名生成图片。 2. 项目结构 项…

科研绘图系列:R语言组合堆积图(stacked barplot with multiple groups)

介绍 通常堆积图的X轴表示样本,样本可能会存在较多的分组信息,通过组合堆积图和样本标签分组信息,我们可以得到一张能展示更多信息的可发表图形。 加载R包 knitr::opts_chunk$set(warning = F, message = F) library(tidyverse) library(cowplot) library(patchwork)导入…

hadoop完全分布模式搭建

本次搭建是基于伪分布式进行的&#xff0c;所以配置之前需要搭建好伪分布式 我使用的ubuntu版本见下 虚拟机之前安装过在此不在记录 伪分布式的搭建过程在之前的第一次实验报告上有详细的记录 修改主机名 设置 hosts 文件 ssh 无密码登录 过程不再演示 免密登录成功图 …

2024中国大学生算法设计超级联赛(2)

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;彩笔ACMer一枚。 &#x1f3c0;所属专栏&#xff1a;杭电多校集训 本文用于记录回顾总结解题思路便于加深理解。 &#x1f4e2;&#x1f4e2;&#x1f4e2;传送门 A - 鸡爪解题思…

【反转链表 II】python刷题记录

印象中&#xff0c;这是遍历r2了&#xff0c;还好没放弃。 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def reverseBetween(self, head: Optional…

NLP基础知识2【各种大模型的注意力】

注意力 传统Attention存在的问题优化方向变体有哪些现在的主要变体集中在KVMulti-Query AttentionGrouped-query AttentionFlashAttention 传统Attention存在的问题 上下文约束速度慢&#xff0c;显存占用大&#xff08;因为注意力考虑整体信息&#xff0c;所以每一个位置都要…

如何使用EXCEL访问WinCC中的实时数据实现报表

如果项目已经做好了&#xff0c;不想改动现有项目。那么可以使用 EXCEL 通过 OPC 方式访问 WinCC 项目的数据。预先定义好 EXCEL 表格样式&#xff0c;通过以下方式实现。通过以下步骤打开 EXCEL 中的 VB 编辑器 引用 WinCC 提供的 OPC 客户端 Control 控件: Siemens OPC DAAut…

LeetCode 415.字符串相加 C++写法

LeetCode 415.字符串相加 C写法 思路&#x1f914;&#xff1a; 首先不能用stoi和tostring来做&#xff0c;如果给一个很大的数那一定存不下。我们可以从后往前一位一位的取&#xff0c;创建一个变量存储进位用于计算下一位数&#xff0c;之后取模得到当前数字&#xff0c;每一…

Python 机器学习求解 PDE 学习项目——PINN 求解一维 Poisson 方程

本文使用 TensorFlow 1.15 环境搭建深度神经网络&#xff08;PINN&#xff09;求解一维 Poisson 方程: − Δ u f in Ω , u 0 on Γ : ∂ Ω . \begin{align} -\Delta u & f \quad & \text{in } \Omega,\\ u & 0 \quad & \text{on } \Gamma:\partial \Om…

Spring Cloud微服务项目公共类抽取

在微服务架构中&#xff0c;代码的重用性和维护性是非常重要的。Spring Cloud 提供了丰富的工具和框架来帮助我们构建和管理微服务应用&#xff0c;但随着项目规模的扩大&#xff0c;我们会遇到大量的重复代码和相似的逻辑。在这种情况下&#xff0c;抽取公共类成为提高代码质量…

txt格式单词导入有道词典生词本 (java代码方式)

txt格式单词导入有道词典生词本 (java代码方式) 首先要求txt文档里单词的格式&#xff0c;大概需要像这种&#xff1a; 每行是一个单词&#xff0c;格式为&#xff1a;英文单词空格词性单词意思。 注意 导出单词本的名字就是你 txt 文件的名字 我这里是 公共英语三级 单词本 …