Elasticsearch 完整格式的 URL 进行分词,有什么好的解决方案吗?

1、问题描述

deef3946e57c6a8fcdaed03e53ce4439.png

我想对完整格式的 url 进行分词,请问有什么好的解决方案吗?

比如:https://www.abc.com/any/path?param_1=so+me&param-2=other#title

看了官方的分词器,感觉没啥合适的?

预处理的话,又不知道该怎么处理更合适?

因为我们的数据量比较大,不太想用 pattern,感觉集群的压力会升高?

我看这个分词器会把识别的 url 当作一个token,但我想实现的是,对 url 尽可能保证精准的拆分。

2、URL 有哪些分词器?

昨天跟 Elastic 官方布道师刘晓国老师一起直播讲 Elastic 认证的时候,刘老师提到:“不是每个人都把每个语法知识点都记得非常清楚,也没有必要。用到的时候查官方文档就可以”。

是这个道理,URL 自定义分词并没有那么常见。那咱们看看官方支持哪些吧?都拎出来用一下,不行就再想办法。

整体看下来直接和 URL 直接相关的就一个:UAX URL email

间接相关的还有:path_hierarchy 分词、char_group 分词(可配置分割字符)。

无法之法就是挨个试一遍!

3、URL 分析器逐个验证

3.1 UAX URL email 分词

3.1.1 UAX URL email 分词功能

UAX URL email 分词器专门用于处理包含 URL 和电子邮件地址的文本。

它不仅能够正确识别和分词 URL,还可以处理电子邮件地址,并将其分割为有意义的部分。

3.1.2 UAX URL email 分词用途

UAX URL email 分词器适用于文本中包含电子邮件或 URL 的场景,确保这些特殊字符不会被简单地分割成无意义的碎片。

3.1.3 UAX URL email 分词配置示例及验证

POST _analyze
{"tokenizer": "uax_url_email","text": "Email me at john.smith@global-international.com"
}

分词后的结果是:

{"tokens": [{"token": "Email","start_offset": 0,"end_offset": 5,"type": "<ALPHANUM>","position": 0},{"token": "me","start_offset": 6,"end_offset": 8,"type": "<ALPHANUM>","position": 1},{"token": "at","start_offset": 9,"end_offset": 11,"type": "<ALPHANUM>","position": 2},{"token": "john.smith@global-international.com","start_offset": 12,"end_offset": 47,"type": "<EMAIL>","position": 3}]
}

281690106d7ac6f5800549c358a6830b.png

从执行结果看出,单词分词,URL 单独作为一个 token 词项单元。

这时候能想到,如果用这个分词器处理 https://www.abc.com/any/path?param_1=so+me&param-2=other#title 的时候,不会做切分。

真实验证如下,和我们预期一致。

2ca34c3713857f8f131b4b3e51ab19a8.png

如果对参数 max_token_length 稍加调整,

PUT my-index-000001
{"settings": {"analysis": {"analyzer": {"my_analyzer": {"tokenizer": "my_tokenizer"}},"tokenizer": {"my_tokenizer": {"type": "uax_url_email","max_token_length": 5}}}}
}POST my-index-000001/_analyze
{"analyzer": "my_analyzer","text": "john.smith@global-international.com"
}

执行一下:

991242946b0d7ac53de1d10fdf539793.png

{"tokens": [{"token": "john","start_offset": 0,"end_offset": 4,"type": "<ALPHANUM>","position": 0},{"token": "smith","start_offset": 5,"end_offset": 10,"type": "<ALPHANUM>","position": 1},{"token": "globa","start_offset": 11,"end_offset": 16,"type": "<ALPHANUM>","position": 2},{"token": "l","start_offset": 16,"end_offset": 17,"type": "<ALPHANUM>","position": 3},{"token": "inter","start_offset": 18,"end_offset": 23,"type": "<ALPHANUM>","position": 4},{"token": "natio","start_offset": 23,"end_offset": 28,"type": "<ALPHANUM>","position": 5},{"token": "nal.c","start_offset": 28,"end_offset": 33,"type": "<ALPHANUM>","position": 6},{"token": "om","start_offset": 33,"end_offset": 35,"type": "<ALPHANUM>","position": 7}]
}

咋一看,好像是我们想要的结果。仔细一看,不如咋一看。仔细一看,出了问题?!

在上述操作中使用了 uax_url_email 分词器,这个分词器专门处理 URL 和电子邮件地址,并设置了 max_token_length 为 5,这意味着每个分词的最大长度为 5 个字符(这很关键)。

7cbf0fe54e0ba633606fcc3273d8900b.png

在分析文本 "john.smith@global-international.com" 时,分词器对电子邮件地址进行了分词,结果如下:

"john" 和 "smith" 被分别作为单独的 token,因为它们是以 . 分隔的部分,并且每部分长度在 5 个字符以内。

后面的域名部分 global-international.com 被分割成多个 token,每个 token 长度不超过 5 个字符:"globa"、"inter"、"natio" 这些 token 依次从域名中提取出来。

由于 max_token_length 被限制为 5,长的单词被截断,如 global 被拆分为 "globa" 和 "l"。

最终结果是,整个电子邮件地址被分成 8 个 token,每个 token 的长度 不超过 5 个字符

这个分词器对于处理电子邮件地址和 URL 等结构化文本非常有用,同时通过设置 max_token_length 可以控制分词的粒度。

但,截断的处理显然不符合预期。

3.2 path_hierarchy 分词

3.2.1 path_hierarchy 分词功能

path_hierarchy 分词器主要用于处理文件路径、URL 或其他层次结构的字符串。它会逐级分割字符串,并生成所有可能的路径层次。

3.2.2 path_hierarchy 分词用途

适合用于处理文件系统路径、URL 层次结构等,特别是需要检索某一特定层级或更高层级时非常有用。

3.2.3 path_hierarchy 分词使用举例

POST _analyze
{"tokenizer": "path_hierarchy","text": "https://www.abc.com/any/path?param_1=so+me&param-2=other#title"
}

返回结果如下:

29180a74046afc64fed4595350f907d1.png

{"tokens": [{"token": "https:","start_offset": 0,"end_offset": 6,"type": "word","position": 0},{"token": "https:/","start_offset": 0,"end_offset": 7,"type": "word","position": 0},{"token": "https://www.abc.com","start_offset": 0,"end_offset": 19,"type": "word","position": 0},{"token": "https://www.abc.com/any","start_offset": 0,"end_offset": 23,"type": "word","position": 0},{"token": "https://www.abc.com/any/path?param_1=so+me&param-2=other#title","start_offset": 0,"end_offset": 62,"type": "word","position": 0}]
}

从上面结果可以看出:path_hierarchy 分词器从最顶层(协议部分)开始,一步步解析出路径中的不同层次,生成多个分层级的 token,每个 token 表示 URL 的某个级别。

这个分词器会对路径中的每一层做分解,但它并不会解析 URL 中的查询参数、片段等部分。

这种分词方式对于处理层次化的 URL 非常有用,适合需要检索某一级 URL 层次的场景。例如,用户可以搜索整个网站、某个目录或具体路径。

3.3 char_group 分词(可配置分割字符)

3.3.1 char_group 分词功能

char_group 分词器允许用户定义分割字符集,例如可以自定义将 . 或 / 作为分割符,从而实现对 URL 进行特定模式的分词。

3.3.2 char_group 分词器用途

适合需要灵活处理 URL 或路径的场景,用户可以根据具体需求配置分割字符。

要对完整格式的 URL 进行精准的分词,同时又要在大数据量的情况下避免增加集群压力,建议使用 char_group 分词器。

char_group 分词器效率高,适合处理大量数据,因为它不使用正则表达式,不会像 开篇提到的 pattern 正则分词器那样消耗大量资源。

3.3.3 char_group 分词使用范例

我们可以配置 char_group 分词器,根据 URL 中常见的分隔符进行分词,例如 ** :, /, ?, &, =, +, #, -, _, . ** 等。

这些字符可以帮助你将 URL 拆分成有意义的部分,如协议、域名、路径、查询参数等。

详见官方文档;

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

以下是具体的实现方案:

PUT your_index
{"settings": {"analysis": {"tokenizer": {"url_tokenizer": {"type": "char_group","tokenize_on_chars": ["whitespace",":","/","?","&","=","+","#","-","_","."]}},"analyzer": {"url_analyzer": {"tokenizer": "url_tokenizer","filter": ["lowercase"]}}}},"mappings": {"properties": {"url": {"type": "text","analyzer": "url_analyzer"}}}
}

上述定义解读如下:

  • url_tokenizer:

使用 char_group 分词器,根据指定的字符进行分词。

  • tokenize_on_chars:

定义了分词的字符集,包括 URL 中常见的分隔符。

  • url_analyzer:

使用 url_tokenizer 作为分词器,并添加了 lowercase 过滤器,将所有词元转换为小写。

开篇问题测试如下:

GET your_index/_analyze
{"analyzer": "url_analyzer","text": "https://www.abc.com/any/path?param_1=so+me&param-2=other#title"
}

返回结果:

e5c29a16f9931d5089243737fe243375.png

{"tokens": [{"token": "https","start_offset": 0,"end_offset": 5,"type": "word","position": 0},{"token": "www","start_offset": 8,"end_offset": 11,"type": "word","position": 1},{"token": "abc","start_offset": 12,"end_offset": 15,"type": "word","position": 2},{"token": "com","start_offset": 16,"end_offset": 19,"type": "word","position": 3},{"token": "any","start_offset": 20,"end_offset": 23,"type": "word","position": 4},{"token": "path","start_offset": 24,"end_offset": 28,"type": "word","position": 5},{"token": "param","start_offset": 29,"end_offset": 34,"type": "word","position": 6},{"token": "1","start_offset": 35,"end_offset": 36,"type": "word","position": 7},{"token": "so","start_offset": 37,"end_offset": 39,"type": "word","position": 8},{"token": "me","start_offset": 40,"end_offset": 42,"type": "word","position": 9},{"token": "param","start_offset": 43,"end_offset": 48,"type": "word","position": 10},{"token": "2","start_offset": 49,"end_offset": 50,"type": "word","position": 11},{"token": "other","start_offset": 51,"end_offset": 56,"type": "word","position": 12},{"token": "title","start_offset": 57,"end_offset": 62,"type": "word","position": 13}]
}

从结果看,基本符合预期。

4、char_group 优势及注意事项

4.1 char_group 优势

可总结为三条:高效、精准、可扩展。

高效:char_group 分词器不使用正则表达式,性能优于 pattern 分词器,适合大数据量场景。

精准:根据指定的字符进行分词,能够精确地拆分 URL 的各个组成部分。

可扩展:可以根据需要调整 tokenize_on_chars 中的字符,定制分词规则。

4.2 char_group 注意事项

如果需要更复杂的分词逻辑,例如基于特定模式的拆分,可以考虑使用 simple_pattern_split 分词器。

它比 pattern 分词器更高效,因为它使用了不支持回溯的简化正则表达式。

但在本文开篇提到的场景中,char_group 分词器已经足够满足需求。

由于 URL 中可能包含编码字符或特殊符号,我们可以根据实际情况调整分词字符集。

5、小结

没有方案或者网上搜不到方案,AI 不能提供具体方案的时候,可以挨个试一下已有方案,逐步找到适合自己业务场景的最佳方案。

使用 char_group 分词器能够在不增加集群压力的情况下,实现对完整 URL 的精准分词。该方案简单高效,适合处理大量数据。

更多推荐

  1. Elasticsearch 使用误区之一——将 Elasticsearch 视为关系数据库!

  2.   Elasticsearch 使用误区之二——频繁更新文档

  3. Elasticsearch 使用误区之三——分片设置不合理

  4. Elasticsearch 使用误区之四——不合理的使用 track_total_hits

  5. Elasticsearch 使用误区之五——单次请求获取大量数据

  6.    《一本书讲透 Elasticsearch》读者群的创新之路

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

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

00253d23e6fa9edd4a9502ccd7be5cd1.png

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

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

elastic6.cn——ElasticStack进阶助手

0f9d280d515f022081525e4f3d726f73.gif

抢先一步学习进阶干货!

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Unity对象池的高级写法 (Plus优化版)

唐老师关于对物体分类的OOD的写法确实十分好&#xff0c;代码也耦合度也低&#xff0c;但是我有个简单的写法同样能实现一样的效果&#xff0c;所以我就充分发挥了一下主观能动性 相较于基本功能&#xff0c;这一版做出了如下改动 1.限制了对象池最大数量&#xff0c;多出来的…

C++11 可变的模板参数

前言 本期我们接着继续介绍C11的新特性&#xff0c;本期我们介绍的这个新特性是很多人都感觉抽象的语法&#xff01;它就是可变的模板参数&#xff01; 目录 前言 一、可变的模板参数 1.1可变的参数列表 1.2可变的参数包 1.3可变参数包的解析 • 递归展开解析 • 逗号…

微服务Docker相关指令

1、拉取容器到镜像仓库 docker pull xxx //拉取指令到 镜像仓库 例如 docker pull mysql 、docker pull nginx docker images //查看镜像仓库 2、删除资源 2.1、删除镜像仓库中的资源 docker rmi mysql:latest //删除方式一&#xff1a;格式 docker rmi 要…

【解密 Kotlin 扩展函数】扩展函数的创建(十六)

导读大纲 1.1 为第三方的类添加方法: 扩展函数 1.1 为第三方的类添加方法: 扩展函数 Kotlin 的主题之一是与现有代码的平滑集成 即使是纯 Kotlin 项目,也是构建在 Java 库之上的 如 JDK、Android 框架和其他第三方框架 而当你将 Kotlin 集成到 Java 项目中时 你还要处理尚未或不…

python爬虫:将知乎专栏文章转为pdf

欢迎关注本人的知乎主页~ 实现思路 用户输入专栏ID&#xff1a; 代码首先提示用户输入一个知乎专栏的ID&#xff0c;默认值为 c_1747690982282477569。输入的ID用于构建API请求的URL。 发送HTTP请求&#xff1a; 使用 requests.get() 向知乎API发送GET请求&#xff0c;获取指定…

【QGIS入门实战精品教程】6.1:QGIS根据属性条件查询数据(SQL表达式)

文章目录 一、字段过滤二、高级过滤(表达式)一、字段过滤 对于单个字段的查询,可以采用字段过滤,例如,从县区数据中,根据NAME字段,查找出县级市玉门市。操作为:右键县区→打开属性表: 点击左下角,选择name字段。 输入玉门市,回车,选择查找除的属性表记录,此时图斑…

【Linux】入门【更详细,带实操】

Linux全套讲解系列&#xff0c;参考视频-B站韩顺平&#xff0c;本文的讲解更为详细 目录 1、课程内容 2、应用领域 3、概述 4、 Linux和Unix 5、VMware15.5和CentOS7.6安装 6、网络连接三种方式 7、虚拟机克隆 8、虚拟机快照 9、虚拟机迁移删除 10、vmtools 11、目录…

set-ExecutionPolicy RemoteSigned 提示不是内部或外部命令,也不是可运行的程序或批处理文件

这个错误一般发生在使用命令提示符或者PowerShell窗口中找不到set-ExecutionPolicy RemoteSigned。如果你想在命令提示符或者PowerShell窗口运行set-ExecutionPolicy RemoteSigned&#xff0c;你需要搜索打开Window PowerShell ISE&#xff0c;并以管理员身份打开&#xff0c;输…

基于微信小程序的美食外卖管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Tomcat系列漏洞复现

CVE-2017-12615——Tomcat put⽅法任意⽂件写⼊漏洞 漏洞描述 当 Tomcat运⾏在Windows操作系统时&#xff0c;且启⽤了HTTP PUT请求⽅法&#xff08;例如&#xff0c;将 readonly初始化参数由默认值设置为false&#xff09;&#xff0c;攻击者将有可能可通过精⼼构造的攻击请求…

身份安全风险不断上升:企业为何必须立即采取行动

在推动安全AI 模型的过程中&#xff0c;许多组织已转向差异隐私。但这种旨在保护用户数据的工具是否阻碍了创新&#xff1f; 开发人员面临一个艰难的选择&#xff1a;平衡数据隐私或优先考虑精确结果。差分隐私可以保护数据&#xff0c;但通常以牺牲准确性为代价——对于医疗保…

某省公共资源交易中心爬虫逆向分析

目标网站 aHR0cHM6Ly95Z3AuZ2R6d2Z3Lmdvdi5jbi8jLzQ0L3NjenQteHEvP3VzZXJJZD02NzM4OTg2MzkyNjA3NzAzMDQmcm93SWQ9NTI1MDYyMDI2ODg0NzE2NTQ0JnRpbWU9MjAwOC0xMS0yNiZjZXJ0aWZpY2F0ZU5vPTkxNDQwOTA0NjgyNDI2MzU4QyZjZXJ0aWZpY2F0ZVR5cGU9Mjg 一、抓包分析 请求头参数加密 二、…

【学习笔记】手写 Tomcat 五

目录 一、优化 Servlet 创建一个抽象类 继承抽象类 二、三层架构 业务逻辑层 数据访问层 1. 在 Dao 层操作数据库 2. 调用 Dao 层&#xff0c;实现业务逻辑功能 3. 调用 Service 层&#xff0c;响应数据 测试 三、数据库连接池 1. 手写数据库连接池 2. 创建数据库…

2024年9月19日---关于ES6(2)

五 异步编程 5.1 回调函数 5.1.1 概念 回调函数(callback function)&#xff0c;当一个函数作为参数传入另一个参数中&#xff0c;并且它不会立即执行&#xff0c;只有当满足一定条件后该函数才可以执行&#xff0c;这种函数就称为回调函数。 你可以将其理解为 回头再调用的…

GNU编译器(GCC):编译的4个过程及.elf、.list、.map文件功能说明

0 参考资料 GNU-LD-v2.30-中文手册.pdf GNU linker.pdf1 前言 一个完整的编译工具链应该包含以下4个部分&#xff1a; &#xff08;1&#xff09;编译器 &#xff08;2&#xff09;汇编器 &#xff08;3&#xff09;链接器 &#xff08;4&#xff09;lib库 在GNU工具链中&…

开源 AI 智能名片 S2B2C 商城小程序与营销工具的快速迭代

摘要&#xff1a;本文以开源 AI 智能名片 S2B2C 商城小程序为研究对象&#xff0c;探讨在营销工具快速迭代的背景下&#xff0c;该小程序如何借鉴以拼多多为代表的“小程序拼团”、以蘑菇街为代表的“小程序直播”、以花点时间为代表的“小程序按月订花”等经典案例&#xff0c…

数据集-目标检测系列-摩托车检测数据集 motorcycle >> DataBall

数据集-目标检测系列-摩托车检测数据集 motorcycle >> DataBall 数据集-目标检测系列-摩托车&#xff08;motorcycle&#xff09;检测数据集 数据量&#xff1a;1W 想要进一步了解&#xff0c;请联系 DataBall。 DataBall 助力快速掌握数据集的信息和使用方式&#xf…

《论软件架构建模技术与应用》写作框架,软考高级系统架构设计师

论文真题 软件架构风格是描述一类特定应用领域中系统组织方式的惯用模式&#xff0c;反映了领域中诸多系统所共有的结构特征和语义特征&#xff0c;并指导如何将各个模块和子系统有效组织成一个完整的系统。分层架构是一种常见的软件架构风格&#xff0c;能够有效简化设计&…

Python语法进阶之路

一、Python基础 1.1 注释 定义和作用 对代码解释说明&#xff0c;增强可读性 单行注释 # 多行注释 """ 这是一个多行注释 """ 1.2 变量及变量类型 定义和作用 计算机目的是计算&#xff0c;编程是为了更方便计算&#xff0c;计算对象就是…

论前端框架的对比和选择 依据 前端框架的误区

前端框架的对比和选择依据 在前端开发中&#xff0c;有多种框架可供选择&#xff0c;以下是一些常见前端框架的对比和选择依据&#xff1a; 一、Vue.js 特点&#xff1a; 渐进式框架&#xff0c;灵活度高&#xff0c;可以逐步引入到项目中。学习曲线相对较平缓&#xff0c;容…