Elasticsearch 8.X 复杂分词搞不定,怎么办?

1、实战问题

球友提问:我想停用所有纯数字的分词 ,  官网上的这个方法好像对ik分词器无效!

11d354d8a70b27a5cd71dfd87241a6e6.png

有没有什么别的方法啊,  chart gpt 说分词可以用正则匹配   但是测试好像是不行的  我的es版本是 8.5.3。

2、进一步沟通后,得到问题最精准描述

我的查询内容可能是:"北京市海淀区清华园10栋105",ik_smart 中文分词结果为:“北京市”、“海淀区”、“清华园”、“10栋”、105。

329c6198821deba882bb530ed6c4d7a4.png

用户期望:只想把分词后,是纯数字的排除掉。也就是说:期望最终分词结果为:“北京市”、“海淀区”、“清华园”、“10栋”。

更进一步说:10栋是个分词,用户期望检索分词结果:“10栋”。但是105的意义不大,用户期望分词阶段把类似“105”的纯数字分词单元去掉。

3、解决方案探讨

有没有现成分词器可以满足用户的需求呢?目前看,没有!

那怎么办?只能自定义分词器。咱们之前讲过,自定义分词器核心就如下图三部分组成。

10cd09f9856118eaa60c5dba8699a2b5.png

三部分含义如下,结合上面的图会更好理解。

部分含义
Character Filter在分词之前对原始文本进行处理,例如去除 HTML 标签,或替换特定字符。
Tokenizer定义如何将文本切分为词条或 token。例如,使用空格或标点符号将文本切分为单词。
Token Filter对 Tokenizer 输出的词条进行进一步的处理,例如转为小写、去除停用词或添加同义词。

Character Filter 和 Token Filter 的区别如下:

它俩在 Elasticsearch 中都是文本预处理的组件,但它们的处理时机和目标略有不同:

属性Character FilterToken Filter
处理时机在 Tokenizer 之前在 Tokenizer 之后
作用对象原始字符序列词条或 token
主要功能预处理文本,如去除 HTML、转换特定字符对词条进行处理,如转为小写、去除停用词、应用同义词、生成词干等
输出修改后的字符序列处理后的词条列表

本质区别:Character Filter 针对原始的字符级别进行处理,而 Token Filter 针对分词后的词项级别进行处理。

到此为止,再看用户的需求,期望分词后去掉“数字”。那也就是在分词后的 Token filter 处理为上乘方案。

Token filter 怎么处理呢?考虑数字级别统一处理的正则表达式,数字的正则为:“^[0-9]+$”。

^[0-9]+$ 可以被分解为几个部分来解读:

  • ^:这个符号表示匹配的起始位置。也就是说,匹配的内容必须从目标字符串的开头开始。

  • [0-9]:这是一个字符类。它匹配从 0 到 9 的任何一个数字字符。

  • +:这是一个量词。它表示前面的内容(在这里是 [0-9] 字符类)必须出现一次或多次。

  • $:这个符号表示匹配的结束位置。也就是说,匹配的内容必须直到目标字符串的结尾。

所以,整体上,这个正则表达式的含义是:字符串的开头到结尾之间只包含一到多个数字字符,并且没有其他任何字符。

例如:

  • "123" 符合该正则。

  • "0123" 也符合。

  • "abc"、"123a" 或 "a123" 都不符合。

一句话,该正则表达式基本达到用户的需求。

实际实现的时候我们发现,对应 filter 环节的:"pattern_replace-tokenfilter"过滤器。该过滤会实现字符级别的替换,我们可以将正则匹配的数字替换为某个字符,比如“”空格字符。

但,还没有达到要求,空格字符用户期望是剔除。这时候,我们又得考虑“”空格如何剔除。

查阅 filter 官方文档知道,有个“analysis-length-tokenfilter”的过滤器,将最小长度设置为1,就能过滤掉长度为0的空格字符。

自此,方案初步敲定。

4、敲定和初步验证解决方案

经过上述的讨论。我们分三步走战略。

  • step 0: 分词器依然选择 ik_smart,和用户需求高度一致。

  • step 1:找出数值数据,使用正则过滤 "pattern_replace filter” 实现。==> 正则表达式 ^[0-9]+$ 替换为特定的字符==> ""。

  • Step 2:  删除空格,借助 length filter 实现。==> lenth > 1 小范围验证一下:

GET /_analyze
{"tokenizer": "ik_smart","filter": [{"type": "pattern_replace","pattern": "^[0-9]+$","replacement": ""},{"type": "length","min": 1}],"text": "11111111北京市10522222海淀区1053333清华园10栋105"
}

在将输入文本复杂化处理后,分词结果依然能达到预期。

64649c59d0ca2e89f443d74235166d7c.png

5、实操实现自定义分词

有了前面的初步实现,自定义分词就变得容易。

DELETE my-index-20230811-000002
PUT my-index-20230811-000002
{"settings": {"analysis": {"analyzer": {"my_custom_analyzer": {"tokenizer": "ik_smart","filter": ["regex_process","remove_length_lower_1"]}},"filter": {"regex_process": {"type": "pattern_replace","pattern": "^[0-9]+$","replacement": ""},"remove_length_lower_1": {"type": "length","min": 1}}}},"mappings": {"properties": {"address":{"type":"text","analyzer": "my_custom_analyzer"}}}
}POST my-index-20230811-000002/_analyze
{"text": ["1111北京市3333海淀区444444清华园10栋105"],"analyzer": "my_custom_analyzer"
}

索引定义解读如下:

部分子部分名称描述
SettingsAnalyzermy_custom_analyzer使用的分词器: ik_smart
- 使用的过滤器: regex_process, remove_length_lower_1
SettingsFilterregex_process类型: pattern_replace
匹配全数字的模式,并替换为空字符串
SettingsFilterremove_length_lower_1类型: length
确保仅保留长度大于或等于1的词条
MappingsPropertiesaddress类型: text
使用的分析器: my_custom_analyzer

上 述配置的主要目的是:创建一个自定义的analyzer,该analyzer可以处理中文文本,将纯数字的token替换为空,并确保分析结果中不包含空token。

最终结果如下,达到预期效果。

902839516fbd1e365b2abde5274c6f58.png

6、小结

当传统默认分词不能达到我们特定的、复杂的需求的时候,记得还有一招:自定义分词。

自定义分词记住三部分组成后,拆解一下复杂问题的需求,问题就会迎刃而解。

视频解读如下:

欢迎大家关注下我的视频号,不定期分享 Elasticsearch 实战进阶干货!

7、参考

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-overview.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-length-tokenfilter.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-pattern_replace-tokenfilter.html

推荐阅读

  1. 全网首发!从 0 到 1 Elasticsearch 8.X 通关视频

  2. 重磅 | 死磕 Elasticsearch 8.X 方法论认知清单

  3. 如何系统的学习 Elasticsearch ?

  4. 2023,做点事

  5. Elasticsearch自定义分词,从一个问题说开去

  6. Elasticsearch 自定义分词同义词环节的这个细节不大好理解......

52d2be9902d7e0b68a3095095e183ae7.jpeg

更短时间更快习得更多干货!

和全球 近2000+ Elastic 爱好者一起精进!

f6a34a4c323c5139928022b198d7050d.gif

大模型时代,抢先一步学习进阶干货!

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

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

相关文章

一文读懂!一年耗能堪比2个三峡电站的大数据中心,背后竟隐藏着这些秘密......

全国大数据中心1年的能耗规模相当于2个三峡电站一整年的发电量,这是为什么? 大数据中心每耗费1度电,只有一半用在了“计算”上面,其他的都应用在散热、照明等方面到底是怎么回事? 为什么说在算力上每投入1元&#xff0…

Games101学习笔记 - MVP矩阵

MV矩阵(模型视图变换) 目的,把摄像机通过变换移动的世界坐标远点,并且朝向与Z轴的负方向相同。这个变换就是模型试图变换。 因为移动了相机,如果想保持正确的渲染的话,那么对应的物体需要要和相机保持相对…

尼科彻斯定理-C语言/Java

描述 验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。 例如: 1^31 2^335 3^37911 4^313151719 输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。&…

13-把矩阵看作是对系统的描述

探索矩阵乘法:更深刻的理解与应用视角 🧩🔍 引言 📖 在我们进一步探讨矩阵乘法之前,让我们从不同的角度来理解什么是矩阵,以及如何将矩阵视为一个系统。我们之前已经介绍了矩阵的基本概念和运算&#xff…

Python Opencv实践 - 图像平移

import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_COLOR)#图像平移 #cv.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) # M是仿射变换矩阵,对于平移来说M是一…

点云基础知识介绍

目录 一、点云数据采集1. 图像衍生点云2. 激光雷达点云3. RGB- D点云4. SAR点云 二、点云特征三、点云应用四、基准数据集 本文由CSDN点云侠原创,原文链接。爬虫网站自重,把自己当个人。 一、点云数据采集 在计算机视觉和遥感中,点云的获取主…

如何微调优化你的ChatGPT提示来提高对话质量

ChatGPT会话质量很大程度上取决于微调优化提示的艺术。本文旨在阐明微调提示的复杂性,以确保你可以充分发挥ChaGPT这一颠覆性工具的潜力。 与ChatGPT对话的关键部分是“提示”。即:你输入的问题或陈述,它决定了人工智能的响应。类似于引导对…

时序预测 | MATLAB实现基于LSTM长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)

时序预测 | MATLAB实现基于LSTM长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价) 目录 时序预测 | MATLAB实现基于LSTM长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)预测结果基本介绍程序设计参考资料 预测结果 基本介绍 Matlab实现LSTM长短期记忆神经…

word横向页面侧面页码设置及转pdf后横线变竖线的解决方案

在处理材料的时候,会遇到同一个文档里自某一页开始,页面布局是横向的,这时候页码要设置在侧面,方法是双击页脚,然后在word工具栏上选择“插入”——>“文本框”——>“绘制竖版文本框”,然后在页面左…

RocketMQ 5.1.0 源码详解 | Producer 发送流程

文章目录 初始化DefaultMQProducer实例发送流程DefaultMQProducer#sendDefaultMQProducerImpl#sendMQClientInstance#updateTopicRouteInfoFromNameServer使用特定 topic 获取路由信息使用默认 topic 获取路由信息 DefaultMQProducerImpl#sendDefaultImpl发送流程总结 初始化De…

手撕Java集合——链表

链表 一、链表概念特性二、不带头单向非循环链表实现🍑1、定义结点🍑2、打印链表🍑3、使用递归逆序打印链表🍑4、头插🍑5、尾插🍑6、指定位置插入🍑7、查找是否包含关键字key是否在单链表当中&a…

C++_模板初阶

在面向对象中,我们可以使用重载来实现多态。 但是问题在于,重载的函数仅仅是类型不同,代码复用率比较低,只要有新的类型出现时,就要增加对应的函数;另一方面它的代码可维护性比较低,一个出错可…