Manticore Search 中文分词搜索入门

Manticore Search 3.1.0 版引入了一种基于ICU 文本分割算法的中文文本分割新方法,该算法遵循第二种方法 - 基于字典的分割。

ICU 是一组开源库,为软件应用程序提供 Unicode 和全球化支持。与许多其他功能一起,它解决了文本边界确定的任务。 ICU 算法在文本范围内定位单词、句子、段落的位置,或者在显示文本时识别适合换行的位置。

本文截稿时,在 Manticore 的讨论区很多人反馈 ICU 似乎没有 jieba 分词器对中文分词处理的更好,Manticore作者也已经将 jieba 分词器的集成纳入后续的支持计划。

Manticore 中 ICU 分词的算法可以简单描述如下:

  • 原始文本被视为符号数组。

  • 然后 Manticore 遍历数组,如果找到一组 * 中文符号,它会将其传递给 ICU 库进行处理。

  • 中文文本的分段部分替换了原始的未分段部分。

  • 其他自然语言处理算法(charset_table、wordforms等)适用于修改后的文本,就像在常见的分割工作流程中一样。

要启用 ICU-Chinese 分词,必须在创建表时添加以下索引配置选项:

  • morphology = ‘icu_chinese’

  • charset_table = ‘chinese’ 或者 charset_table = ‘non_cjk,chinese’

当一篇文章包含中文和英文时可以考虑设置 charset_table = ‘non_cjk,chinese’

示例步骤如下

1、连接到 manticore

mysql -P 9306 -h0 

2、创建表

# 1、创建表
mysql> CREATE TABLE test_record (form_id bigint, form_data json, author string attribute indexed, content text) charset_table = 'chinese' morphology = 'icu_chinese';# 2、查看表结构
mysql> desc test_record;
+-----------+--------+-------------------+
| Field     | Type   | Properties        |
+-----------+--------+-------------------+
| id        | bigint |                   |
| author    | string | indexed attribute |
| content   | text   | indexed stored    |
| form_id   | bigint |                   |
| form_data | json   |                   |
+-----------+--------+-------------------+

中英文混合时候参考选用 charset_table = 'non_cjk,chinese'

更多字段类型详见官方文档,地址:https://manual.manticoresearch.com/Creating_a_table/Data_types#Character-data-types

3、插入测试数据

mysql> INSERT INTO test_record (form_id, form_data, author, content) VALUES ( 226810975896997888, '{"number_1600348358244":"23347","input_1600348411983":"","input_1600348225548":"6224439990006413028","time_1600348183508":"14:36:46","input_1600348282096":"昆山市人民法院","date_1600348389097":"2022-01-14","textarea_1600348453979":"","input_1600348238915":"GADJ00020211182885","input_1600348211548":"","date_1600348174740":"2021-01-14","input_1600348428388":"","radio_1600348126943":"1","input_1600348336862":"冻结"}', '张三', '清华大学' );mysql> INSERT INTO test_record (form_id, form_data, author, content) VALUES ( 226810975896997888, '{"date_1600345666309":"2017-08-16","input_1610335861888":"3052261","input_1600345921986":"孙善广","textarea_1600345727801":"撤销","input_1602568493757":"昆山德立亚企业管理有限公司","input_1600345853347":"1673","input_1600345648905":"274552978554269699","input_1600345839985":"3052261012019000001673","input_1600345935496":"15298824131"}', '李四', '一位牙医和一只狗在中国古代杀死一个疯子的惊人书信' );mysql> INSERT INTO test_record (form_id, form_data, author, content) VALUES ( 226810975896997888, '{"number_1604892340550":"20","input_1604891602279":"2005","input_1604891603314":"王海燕","date_1604891845251":"2021-01-14","input_1604891608805":"蒋琮(2222)","input_1604891603984":"371311198305043420","input_1604891608483":"B1","date_1604891858785":"2021-01-14","input_1604891608176":"HR65528845","input_1604891599203":"A0020","number_1604892324841":"1"}', '李佳', '一个相扑摔跤手和一个必须在Baloon追捕法医心理学家的猎人的难以置信的插曲' );mysql> INSERT INTO test_record (form_id, form_data, author, content) VALUES ( 269501011993878528, '{"date_1600345666309":"2019-11-14","input_1610335861888":"3052261","input_1600345921986":"郭云磊","textarea_1600345727801":"撤销","input_1602568493757":"昆山市康跃可喜安医疗器械有限公司","input_1600345853347":"2145","input_1600345648905":"274552905254612995","input_1600345839985":"3052261012017000002145","input_1600345935496":"13776098096"}', '小单', '买新的Apple电脑' );

4、分词测试

# 使用 call keywords,第一个参数为内容,第二个参数为表名
mysql> call keywords ('买新的Apple电脑', 'test_record');
+------+-----------+------------+
| qpos | tokenized | normalized |
+------+-----------+------------+
| 1    |||
| 2    | 新的      | 新的       |
| 3    | 电脑      | 电脑       |
+------+-----------+------------+
mysql> call keywords ('一位牙医和一只狗在中国古代杀死一个疯子的惊人书信', 'test_record');
+------+-----------+------------+
| qpos | tokenized | normalized |
+------+-----------+------------+
| 1    | 一位      | 一位       |
| 2    | 牙医      | 牙医       |
| 3    |||
| 4    | 一只      | 一只       |
| 5    |||
| 6    |||
| 7    | 中国      | 中国       |
| 8    | 古代      | 古代       |
| 9    | 杀死      | 杀死       |
| 10   | 一个      | 一个       |
| 11   | 疯子      | 疯子       |
| 12   |||
| 13   | 惊人      | 惊人       |
| 14   | 书信      | 书信       |
+------+-----------+------------+
mysql> call keywords ('清华大学', 'test_record');
+------+--------------+--------------+
| qpos | tokenized    | normalized   |
+------+--------------+--------------+
| 1    | 清华大学     | 清华大学     |
+------+--------------+--------------+

注:从测试 买新的Apple电脑 分词结果我们可以看到,Apple 消失了,那是因为我们设定的 charset_table 只是 chinese,如果你希望中文和英文都被分词,则你需要设置 charset_table = 'non_cjk,chinese',可以自行测试验证。

5、查询数据

5.1、普通字段查询
mysql> select id, form_id, author from test_record where form_id = 226810975896997888;
+---------------------+--------------------+--------+
| id                  | form_id            | author |
+---------------------+--------------------+--------+
| 3461355430494601233 | 226810975896997888 | 李四   |
| 3461355430494601234 | 226810975896997888 | 李佳   |
| 3461355430494601232 | 226810975896997888 | 张三   |
+---------------------+--------------------+--------+
5.2、对 string 字段进行正则查询
mysql> select id, form_id, author from test_record where form_id = 226810975896997888 and regex(author, '李.*');
+---------------------+--------------------+--------+
| id                  | form_id            | author |
+---------------------+--------------------+--------+
| 3461355430494601234 | 226810975896997888 | 李佳   |
| 3461355430494601233 | 226810975896997888 | 李四   |
+---------------------+--------------------+--------+

注:如官方文档中对 REGEX函数的描述 The REGEX(attr,expr) function returns 1 if a regular expression matches the attribute's string, and 0 otherwise. It works with both string and JSON attributes. 所示,regex 目前只能用于 string 和 json 类型的字段

5.3、对索引字段使用 match 进行搜索

只有被索引的字段才可以使用 match 进行搜索,text 类型的字段默认为 stored + indexedstring 字段默认为 attribute,但是我们可以手工为 string 字段设置 indexed 属性使之也被索引,这样 string 也可以使用 match 匹配搜索。

5.3.1、从所有索引字段搜索
# match 不指定具体字段的时,会从所有支持索引的字段中去匹配(一般包含明确指定indexed的string字段和text字段)mysql> select id, form_id, author, content from test_record where match('牙医');
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
| id                  | form_id            | author | content                                                                  |
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
| 3461355430494601233 | 226810975896997888 | 李四   | 一位牙医和一只狗在中国古代杀死一个疯子的惊人书信                         |
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
mysql> select id, form_id, author, content from test_record where match('李');
+---------------------+--------------------+--------+--------------------------------------------------------------------------------------------------------+
| id                  | form_id            | author | content                                                                                                |
+---------------------+--------------------+--------+--------------------------------------------------------------------------------------------------------+
| 3461355430494601234 | 226810975896997888 | 李佳   | 一个相扑摔跤手和一个必须在Baloon追捕法医心理学家的猎人的难以置信的插曲                                 |
| 3461355430494601233 | 226810975896997888 | 李四   | 一位牙医和一只狗在中国古代杀死一个疯子的惊人书信                                                       |
+---------------------+--------------------+--------+--------------------------------------------------------------------------------------------------------+
mysql> select id, form_id, author, content from test_record where match('小单');
+---------------------+--------------------+--------+----------------------+
| id                  | form_id            | author | content              |
+---------------------+--------------------+--------+----------------------+
| 3461355430494601235 | 269501011993878528 | 小单   | 买新的Apple电脑      |
+---------------------+--------------------+--------+----------------------+
mysql> select id, form_id, author, content from test_record where match('清华');
mysql> select id, form_id, author, content from test_record where match('清华大学');
+---------------------+--------------------+--------+--------------+
| id                  | form_id            | author | content      |
+---------------------+--------------------+--------+--------------+
| 3461355430494601232 | 226810975896997888 | 张三   | 清华大学     |
+---------------------+--------------------+--------+--------------+
5.3.2、从明确指定的索引字段搜索
# 语法:match('@field keyworld') 或者 match('@(field1,field2,...) keyworld') mysql> select id, form_id, author, content from test_record where match('@author 牙医');
mysql> select id, form_id, author, content from test_record where match('@(content) 牙医');
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
| id                  | form_id            | author | content                                                                  |
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
| 3461355430494601233 | 226810975896997888 | 李四   | 一位牙医和一只狗在中国古代杀死一个疯子的惊人书信                         |
+---------------------+--------------------+--------+--------------------------------------------------------------------------+# match 指定从多个字段中匹配mysql> select id, form_id, author, content from test_record where match('@(content,author) 张三');
+---------------------+--------------------+--------+--------------+
| id                  | form_id            | author | content      |
+---------------------+--------------------+--------+--------------+
| 3461355430494601232 | 226810975896997888 | 张三   | 清华大学     |
+---------------------+--------------------+--------+--------------+
5.3.3、同时匹配多个关键字
mysql> select id, form_id, author, content from test_record where match('@(content,author) 张三|牙医');
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
| id                  | form_id            | author | content                                                                  |
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
| 3461355430494601233 | 226810975896997888 | 李四   | 一位牙医和一只狗在中国古代杀死一个疯子的惊人书信                         |
| 3461355430494601232 | 226810975896997888 | 张三   | 清华大学                                                                 |
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
5.3.4、多个字段并且关系搜索
# 检索contnet包含“一个”并且author包含“李四”的内容
mysql> select id, form_id, author, content from test_record where match('@content 一个 @author 李四');
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
| id                  | form_id            | author | content                                                                  |
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
| 3461355430494601233 | 226810975896997888 | 李四   | 一位牙医和一只狗在中国古代杀死一个疯子的惊人书信                         |
+---------------------+--------------------+--------+--------------------------------------------------------------------------+

更多关于全文索引的查询语法,详见官方文档中的 Full text operators 章节。

5.3.4、对 json 字段进行查询
# 查询json字段中某一个属性大于指定值的(数字类型比较轻注意正确选用 INTEGER、DOUBLE)
mysql> SELECT * FROM test_record WHERE INTEGER(form_data.input_1600345853347) > 1673;# 对json中的具体字段使用精确查询
mysql> SELECT * FROM test_record WHERE form_data.input_1600345921986 = '郭云磊';# 对json中的字段使用正则匹配查询
mysql> SELECT * FROM test_record WHERE regex(form_data.input_1600345921986, '孙.*');

官方提供了JSON字段查询的仿真教学环境,地址为 https://play.manticoresearch.com/json/,更多内容请探索官方手册。

5.4、查看查询的扩展信息

每执行一个查询后,都可以使用 SHOW META 查看执行过的查询的扩展信息,如下所示:

mysql> select id, form_id, author, content from test_record where match('@(content,author) 张三|牙医');
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
| id                  | form_id            | author | content                                                                  |
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
| 3461355430494601233 | 226810975896997888 | 李四   | 一位牙医和一只狗在中国古代杀死一个疯子的惊人书信                         |
| 3461355430494601232 | 226810975896997888 | 张三   | 清华大学                                                                 |
+---------------------+--------------------+--------+--------------------------------------------------------------------------+
mysql> SHOW META;
+----------------+--------+
| Variable_name  | Value  |
+----------------+--------+
| total          | 2      |
| total_found    | 2      |
| total_relation | eq     |
| time           | 0.000  |
| keyword[0]     | 张三   |
| docs[0]        | 1      |
| hits[0]        | 1      |
| keyword[1]     | 牙医   |
| docs[1]        | 1      |
| hits[1]        | 1      |
+----------------+--------+

总结

实现中文全文搜索看似通过中间件很容易,让分词结果达到自己实际业务期望度并非易事。虽然 Manticore Search 使用 ICU 已经可以轻松的应付大部分中文场景。但是当你深度使用后,可能会发现它对很多自定义词组和灵活组合变幻的中文的支持度仍然达不到我们的预期,对分词的扩展支持目前来说还不够。
不过如文初所述,作者已经计划集成 jieba 分词器(issue),相信在不久的将来支持 jieba 后我们能更灵活的自定义中文词库,来尽可能更准确的满足我们对中文分词的实际业务需求。

中文分词的官方互动教程地址:https://play.manticoresearch.com/icu-chinese/


(END)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab-写入mhd和raw医学图像处理格式文件

作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 mhd和raw是什么? MHD(MetaImage)和RAW(Raw Image Data)是用于医学图像…

算法---二分算法

一:二分法算法分析 1、二分查找算法定义 二分查找又称折半查找,它是一种效率较高的查找方法。 二分查找要求:线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构。 2、基本思想 (1)首先确定该区间的中点位置 (2)将待查的K值与R[mid]比较:若相等…

机器学习实验------AGNES层次聚类方法

机器学习 — AGNES层次聚类方法 第1关:距离的计算 任务描述 本关任务:根据本关所学知识,完成calc_min_dist函数,calc_max_dist函数以及calc_avg_dist函数分别实现计算两个簇之间的最短距离、最远距离和平均距离。 import numpy as np def calc_min_dist(cluster1, clus…

【测试工具】JMeter接口测试的简单使用

事先声明:博主的JMeter是3.3版本的,可能和最新版本的操作有些许差别 测试前的准备工作 1、先添加一个线程组:右击“测试计划”,点击“添加”—》“Threads(Users)”—》“线程组” 2、再添加一个HTTP请求,右击“线程…

基于Hive大数据分析springboot为后端以及vue为前端的的民宿系

标题基于Hive大数据分析springboot为后端以及vue为前端的的民宿系 本文介绍了如何利用Hive进行大数据分析,并结合Spring Boot和Vue构建了一个民宿管理系统。该民民宿管理系统包含用户和管理员登陆注册的功能,发布下架酒店信息,模糊搜索,酒店详情信息展示,收藏以及对收藏的…

Pillow教程03:图像处理的基本步骤+分离split+合并merge+混合blend+composite遮罩

--------------Pillow教程集合--------------- Python项目18:使用Pillow模块,随机生成4位数的图片验证码 Python教程93:初识Pillow模块(创建Image对象查看属性图片的保存与缩放) Pillow教程02:图片的裁剪…

烫烫烫手的结构体大小计算来咯,很烫哦,慢慢消化。自定义类型(一)

emmm,在这炎热的夏天在宿舍吹着空调写着博客也是一件不错的事呢,今天就来来好好盘一下C语言中的自定义类型。 常常会回顾努力的自己,所以要给自己的努力留下足迹。 为今天努力的自己打个卡,留个痕迹吧 2024.03.29 小闭 目录 …

C++项目——集群聊天服务器项目(九)客户端异常退出业务

服务器端应检测到客户端是否异常退出,因此本节来实现客户端异常退出,项目流程见后文 一、客户端异常退出业务流程 (1)在业务模块定义处理客户端异常退出的函数 (2)集群聊天服务器项目(八)提到…

为什么在Python中总是使用【字典】这种类型呢?

你好,我是安然无虞。 文章目录 创建字典新增字典元素update 方法 删除字典元素pop 方法popitem 方法 查找字典元素in 和 in not 操作符get 方法thisdict[key] 修改字典元素遍历字典元素for循环遍历keys方法values方法items方法 合并字典字典中的key 字典常用接口汇…

网际协议 - IP

文章目录 目录 文章目录 前言 1 . 网际协议IP 1.1 网络层和数据链路层的关系 2. IP基础知识 2.1 什么是IP地址? 2.2 路由控制 3. IP地址基础知识 3.1 IP地址定义 3.2 IP地址组成 3.3 IP地址分类 3.4 子网掩码 IP地址分类导致浪费? 子网与子网掩码 3.5 CIDR与…

常见缓存数据库

Redis Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行…

自己动手用ESP32手搓一个智能机器人:ESP32-CAM AI Robot

目录 介绍 硬件需求 软件需求 步骤 总结 源码下载 介绍 ESP32-CAM是一款集成了Wi-Fi和蓝牙功能的微控制器模块,同时还集成了摄像头接口,使其成为一个非常适合构建智能机器人的选择。在本项目中,我将向您展示如何使用ESP32-CAM模块构建…

数据运营分析-详解

一、指标与指标体系 指标体系就是业务逻辑的框架,也是思考业务逻辑的第一步 案例: 老板,我负责的用户活跃,主要考察每天启动产品的注册用户数量,整体来看,每月活跃保持7.3%的增长,是因为渠道团队的拉新活动带来很多新增注册用户,占每月活跃用户的40%,新一年会继续沿…

消息队列的七种经典应用场景

在笔者心中,消息队列,缓存,分库分表是高并发解决方案三剑客。 在职业生涯中,笔者曾经使用过 ActiveMQ 、RabbitMQ 、Kafka 、RocketMQ 这些知名的消息队列 。 这篇文章,笔者结合自己的真实经历,和大家分享…

Linux项目自动化构建工具-make/ makefile及其应用:多文件编写第一个linux程序:进度条(懒人学习必备博文!!!)

目录 1.前言--make/makefile的引入 2.快速上手make/makefile---自动化构建 3.关于依赖关系和依赖方法 4.自动化清理 为什么我们执行编译的时候,make一下就好,清理却要使用make clean? 5. make/makefile是如何知道当前目录下可执行文件是否为最新 6.文件…

在虚拟机ubuntu中端里输入vim filename.不显示vim界面,而是vim可以在以下的 package 找到

1。打开终端 2.输入以下命令来更新软件包列表: sudo apt update 3,输入以下命令来安装vim编辑器: sudo apt install vim 4等待安装完成后,再次输入"vim filename"命令,应该就能正常显示vim界面了。

express实现用户登录和注册接口

目录 1 创建数据库2 连接数据库3 集成ORM库4 创建业务逻辑5 创建路由7 测试接口总结 我们在编写后端接口的时候操作数据库是一种常见的功能需求,express本身并不提供直接操作数据库的能力,需要借助第三方库来操作数据库,本篇讲解一下软件开发…

JavaScript 之 var、let 和 const

JavaScript 之 var、let 和 const 1.作用域2.重新赋值3.重复声明总结 var、let 和 const 都是用来声明变量的关键字,但它们之间有一些重要的区别 1.作用域 var:声明的变量具有函数作用域或全局作用域。 在函数内部声明的变量只能在该函数内部访问&…

【二叉树】Leetcode 543. 二叉树的直径【简单】

二叉树的直径 给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例1: 输入:root [1,2…

基于SpringBoot + Vue实现的在线装修管理系统设计与实现+毕业论文

介绍 系统包含用户、装修队、管理员三个角色 管理员: 管理员管理:管理其他管理员的账号和权限,确保系统管理的层次化和安全性。 装修队管理:审核装修队的资质,管理装修队的人员信息,监控工程进度&#xff…