【elasticsearch】Elasticsearch 7.X Scripting 脚本使用详解
1.概述
转载:Elasticsearch 7.X Scripting脚本使用详解
0、题记
除了官方文档,其他能找到的介绍Elasticsearch脚本(Scripting)的资料少之又少。
一方面:性能问题。
官方文档性能优化中明确指出使用脚本会导致性能低;
另一方面:使用场景相对少。
非复杂业务场景下,基础的增、删、改、查基本上就能搞定。
但,不能否认,在解决复杂业务问题(如:自定义评分、自定义文本相关度、自定义过滤、自定义聚合分析)时,脚本依然是Elasticsearch强悍的利器之一。
本文在官方文档基础上,结合实际业务场景,在Elasticsearch7.3环境下进行脚本使用解读。
1、官方scripting使用建议
Avoid scripts——In general, scripts should be avoided.
If they are absolutely needed, you should prefer the painless and expressions engines.
ebay在性能优化实践中也强调(本文做了扩展延伸):
避免使用脚本查询(script query)计算动态字段。
例如:我们有一个包含大量剧院信息的索引,我们需要查询以"Down"开头的所有剧院。你可能运行一个如下脚本查询:
POST seats/_search
{"query": {"bool": {"filter": {"script": {"script": {"lang": "painless","source": "doc['theatre'].value.startsWith('Down')"}}}}}
}
这个查询非常耗费资源,并且减慢整个系统。
解决方案:
方案一:prefix前缀匹配;实测性能:prefix较scripting性能提升5倍。
方案二:索引时考虑添加一个名为“theatre_prefix”的keyword类型字段。然后我们可以查询"theatre_prefix":"Down"。
2、ES Scripting历史
版本 | 使用脚本 |
< Elasticsearch 1.4 |
MVEL 脚本 |
< Elasticsearch 5.0 |
Groovy 脚本 |
‘>= Elasticsearch 5.0 |
painless 脚本 |
Groovy 的出现是解决MVEL的安全隐患问题
;
但Groovy仍存在内存泄露+安全漏洞问题
,
painless脚本的官宣时间:2016年9月21日。看似很新,截止目前,已经三年左右时间了。
正如其名字:无痛。painless的出现是为了用户更方便、高效的使用脚本。
https://www.elastic.co/cn/blog/painless-a-new-scripting-language
3、Painless Scripting 简介
Painless是一种简单,安全的脚本语言,专为与Elasticsearch一起使用而设计
。它是Elasticsearch的默认脚本语言,可以安全地用于内联和存储脚本。
Painless特点:
性能牛逼:Painless脚本运行速度比备选方案(包括Groovy)快几倍。
安全性强:使用白名单来限制函数与字段的访问,避免了可能的安全隐患。
可选输入:变量和参数可以使用显式类型或动态def类型。
上手容易:扩展了java的基本语法,并兼容groove风格的脚本语言特性。
特定优化:是ES官方专为Elasticsearch脚本编写而设计。
4、Scripting 应用场景
认知前提:
增删改查能解决业务场景80%的问题
,Painless脚本操作一般应用于相对复杂的业务场景中。
常见场景举例如下:
自定义字段
自定义评分
自定义更新
自定义reindex
聚合
其他自定义操作
5、Scripting 使用模板
心中有模板,脚本认知就有了“套路”。
"script": {"lang": "...", "source" | "id": "...", "params": { ... } }
lang
:代表language脚本语言,默认指定为:painless。source
:脚本的核心部分,id应用于:stored script。params
:传递给脚本使用的变量参数。
6、Scripting 实战
6.1 自定义字段
举例:返回原有Mapping未定义的字段值。
如:以my_doubled_field返回my_field字段的翻倍后的结果。
GET my_index/_search
{"script_fields": {"my_doubled_field": {"script": {"lang": "expression","source": "doc['my_field'] * multiplier","params": {"multiplier": 2}}}}
}
注意:这里脚本语言选择的expression
,下一节讲解。
如:返回日期字段中的“年”或“月”或“日”等。
GET hockey/_search
{"script_fields": {"birth_year": {"script": {"source": "doc.born.value.year"}}}
}
6.2 自定义评分
GET my_index/_search
{"query": {"function_score": {"query": {"match": {"text": "quick brown fox"}},"script_score": {"script": {"lang": "expression","source": "_score * doc['popularity']"}}}}
}
6.3 自定义更新
Update:将已有字段值赋值给其他字段。
POST hockey/_update/1
{"script": {"lang": "painless","source": """ctx._source.last = params.last;ctx._source.nick = params.nick""","params": {"last": "gaudreau","nick": "hockey"}}
}
Update_by_query:满足b开头(注意正则)的字段,末尾添加matched。
POST hockey/_update_by_query
{"script": {"lang": "painless","source": """if (ctx._source.last =~ /b/) {ctx._source.last += "matched";} else {ctx.op = "noop";}"""}
}
6.4 自定义reindex
Elasticsearch认证考试题:
有index_a
包含一些文档, 要求创建索引index_b
,通过reindex api
将index_a
的文档索引到index_b
。
要求:
增加一个整形字段,value是index_a的field_x的字符长度;
再增加一个数组类型的字段,value是field_y的词集合。
(field_y是空格分割的一组词,比方"foo bar",索引到index_b后,要求变成[“foo”, “bar”])
POST _reindex
{"conflicts": "proceed","source": {"index": "index_a"},"dest": {"index": "index_b"},"script": {"source": "ctx._source.parts = / /.split(ctx._source.address); ctx._source.tag = ctx._source.city.length();"}
}
语法参考:
https://www.elastic.co/guide/en/elasticsearch/painless/7.3/painless-regexes.html
6.5 聚合
GET /_search
{"aggs": {"genres": {"terms": {"script": {"source": "doc['genre'].value","lang": "painless"}}}}
}
6.6 其他自定义操作
需要结合业务去实践。
7、常见坑及问题
7.1 脚本只有Painless吗?
显然不是,第6节用到的expression 是Lucene’s expressions 脚本语言。
还可以基于脚本引擎自己开发插件实现,
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-engine.html
7.2 怎么界定是expressions 还是Painless?
"lang": "painless",
"lang": "expressions ",
是唯一区分。
7.3 使用painless就百分之百“无痛”,无漏洞后顾之忧了吗?
凡事不能绝对。
核心注意点:
第一:不要root账户下运行Elasticsearch。
第二:不要公开ES路径给其他用户。
第三:不要公开ES路径到互联网。
实战推荐:
1、用户在搜索框中键入文本,文本将直接发送到后台的match、match_phrase、Simple query string或 Suggesters.
2、作为应用程序开发过程的一部分(而非全部)开放上述查询的脚本。
3、使用用户提供的参数运行脚本。
4、文档固定的Mapping结构。
不推荐:
1、用户可以编写任意scripts, queries(检索), _search requests(search请求)。
2、文档结构可以用户自定义。
8、小结
本文讲解了脚本的发展历史、使用场景、应用实战,但相比于实际业务的复杂需求仍然是九牛一毛。
实战中,肯定还会遇到这样、那样的问题。
一方面:欢迎留言交流。
另一方面:多研读官方文档,很多细节值得深究。
N.参考:
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-search-speed.html
https://www.infoq.cn/article/elasticsearch-performance-tuning-practice-at-ebay
https://github.com/laoyang360/deep_elasticsearch/blob/master/es_dsl_study/6.scripting.md
https://github.com/elastic/elasticsearch/issues/19396
https://www.youtube.com/watch?v=3FLEJJ8PsM4
https://blog.csdn.net/u013613428/article/details/78134170
————————————————
版权声明:本文为CSDN博主「铭毅天下」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/laoyang360/article/details/100869751
【elasticsearch】Elasticsearch 7.X Scripting 脚本使用详解相关推荐
- 干货 | Elasticsearch7.X Scripting脚本使用详解
0.题记 除了官方文档,其他能找到的介绍Elasticsearch脚本(Scripting)的资料少之又少. 一方面:性能问题. 官方文档性能优化中明确指出使用脚本会导致性能低: 另一方面:使用场景相 ...
- Elasticsearch之settings和mappings(图文详解)
Elasticsearch之settings和mappings的意义 简单的说,就是 settings是修改分片和副本数的. mappings是修改字段和类型的. 记住,可以用url方式来操作它们,也 ...
- fofa自动化爬虫脚本更新+详解
fofa自动化爬虫脚本更新+详解 起因 最近要用到fofa爬虫,为什么要用爬虫不用api,问就是穷,想起来之前写过一个相关的脚本:Fofa-python-脚本,是很久以前写的了,之前写的时候有点问题, ...
- php事务 面向对象,PHP面向对象之事务脚本模式(详解)
如下所示: /* 事务脚本模式: 类似于thinkphp中的model层,或者说就是操作数据库的类. 个人觉得实践中使用起来还是挺简单方便的,就是SQL语句写死了的话,灵活性就不够. 示例代码如下: ...
- rcs开机启动mysql_linux添加开机自启动脚本示例详解-阿里云开发者社区
linux添加开机自启动脚本示例详解 double2li 2017-04-14 1652浏览量 简介: linux下(以RedHat为范本)添加开机自启动脚本有两种方法,先来简单的;一.在/etc/r ...
- java dtu 采集程序_DTU脚本编程_本地采集脚本指令详解
前言: 通过配置DTU的脚本指令实现DTU定时自动采集,用户只需知道外接仪表.无需再单独增加控制器传感器的采集流程,然后通过编写脚本指令即可让DTU按照用户的流程自动采集.上传数据.脚本实现了基本的开 ...
- Elasticsearch(es) 查询语句语法详解
Elasticsearch 查询语句采用基于 RESTful 风格的接口封装成 JSON 格式的对象,称之为 Query DSL.Elasticsearch 查询分类大致分为全文查询.词项查询.复合查 ...
- 干货 | Elasticsearch 8.X 节点角色划分深入详解
0.问题引出 如果你的 Elasticsearch 集群是 7.9 之前的版本,在配置节点的时候,只会涉及节点类型的概念.我相信大家会对下面的概念比较熟悉: 主节点 数据节点 协调节点 Ingest ...
- java spring启动和终止_springBoot jar启动以停止脚本参数详解
一.启动脚本 Springboot 项目打成jar包后,在Linux环境上一般有如下几种启动方式: 1. "java -jar XXX.jar " 命令结尾没有 "&am ...
最新文章
- java反射 获取参数类型_Java反射带参构造创建对象时如何自动转换参数类型
- hive中groupby优化_Hive数据倾斜
- python打印输出12星座,怎么利用python输出星座
- 45. Element isDefaultNamespace() 方法
- 关于三种主流WEB架构的思考
- 运筹学基础及其matlab,运筹学基础及其MATLAB应用
- STM32F1与STM32CubeIDE编程实例-光敏电阻(LDR)传感器驱动
- linux puppy 安装软件,小芭比linux下载
- 七大顶级编程学习网站
- 删除安卓7.1源码中自带的Japanese IME输入法
- QEMU同步脏页原理
- PS怎样把成图变成素描或者速写稿
- Flash与服务器通信简介
- matlab地球月球卫星关系,Matlab 卫星绕地球旋转演示动画
- JAVA小游戏有源代码,非常详细的注释,以及自己做的答辩PPT
- [论文翻译] Deep Learning
- django2.1.7从0开始搭建一个个人博客网站第5天
- css中zoom和scale
- python并发编程之进程1(守护进程,进程锁,进程队列)
- 【回眸】Study with me!计算机二/三 级(物联网)刷题的心路历程