本文以 ES 6.6.0 版本为例进行演示.

1 关于脚本

ES提供了脚本支持 —— 可以通过Groovy外置脚本(已过时)、内置painless脚本实现各种复杂操作.

—— painless有轻便之意, 使用时直接在语法中调用即可, 无需外置, 也就是不支持通过外部文件存储painless脚本并调用的方法.

// 向ES中插入一条数据:
PUT employee/developer/1
{
"name": "shou feng",
"age": 20,
"salary": 10000
} // 通过GET发送脚本, 允许为每个匹配的文档返回脚本评估(script evaluation)内容:
GET employee/_search
{
"script_fields": {
"change_age_field": { // 该字段不存在 - script fields可以处理未存储的字段
"script": {
"lang": "expression",
"source": "doc['age'] * multiplier", // 获取age字段的值进行计算
"params": {
"multiplier": 2
}
}
}
}
} // 响应结果为:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "employee",
"_type" : "developer",
"_id" : "1",
"_score" : 1.0,
"fields" : {
"change_age_field" : [
40.0
]
}
}
]
}
}

2 脚本使用的最佳实践

Elasticsearch第一次加载一个新脚本时, 会将新脚本编译并存储在缓存中.

编译可能是一个繁重的过程, 如果需要将变量传递给脚本, 建议: 将它们作为命名参数传递给脚本本身(方式①), 而不是硬编码在脚本中(方式②).

(1) 方式① 参数传递:

"source": "doc['age'] * multiplier",
"params": {
"multiplier": 2
}

(2) 方式② 硬编码:

"source": "doc['age'] * 2"

(3) 优劣对比:

  • 每次乘数改变时都必须重新编译第②个版本, 而第①个版本只编译一次.

  • 如果短时间内编译过多的脚本, ES将拒绝带有circuit_breaking_exception错误的新脚本.

  • Elasticsearch默认情况下, 每分钟最多编译15个内联脚本, 可以通过修改 script.max_compilations_rate 的值来更改此设置.

2.1 创建脚本并存储

可以使用_scripts API 将脚本存储在集群状态中, 并从集群状态中检索脚本.

使用_scripts/{id}的方式操作脚本, 具体步骤如下:

(1) 首先在集群状态中创建名为calculate-score的脚本:

POST _scripts/calculate-score
{
"script": {
"lang": "painless",
"source": "Math.log(_score * 2) + params.my_modifier"
}
}

(2) 检索存储的脚本:

GET _scripts/calculate-score

(3) 通过脚本id使用已创建的脚本:

GET _search
{
"query": {
"script": {
"script": {
"id": "calculate-score",
"params": {
"my_modifier": 2 // 传递脚本所需的参数
}
}
}
}
}

(4) 删除脚本:

DELETE _scripts/calculate-score

2.2 脚本的缓存

默认情况下, 所有的脚本都会被缓存到ES集群中, 因此只有当脚本被更新之后, ES才会重新编译它们.

同样, 脚本没有过期时间的说法, 但可以使用script.cache.expire设置更改过期时间.

也可以使用script.cache.max_size配置此脚本缓存的大小, 默认缓存大小为100.

存储脚本的大小限制为65535字节, 可以通过 script.max_size_in_bytes来更改, 但是如果脚本非常大, 就应该考虑相关脚本的实现引擎是否足够优秀.

2.3 Script Field - 脚本字段

脚本字段还可以通过访问_source字段来提取文档的其他字段 —— 使用params ['_source']提取要从中获取的内容.

比如访问_source元字段中message字段的内容, 可以用: "script": "params['_source']['message']"访问.

另外: 理解doc['my_field'].valueparams['_source']['my_field']之间的区别非常重要:

① 使用doc关键字: 将导致该字段的术语加载到内存(缓存)中, 这样脚本的执行速度会更快, 但也会带来更多的内存消耗. 另外, doc […]符号只允许简单的值字段(不能从中返回JSON对象), 并且它只对非分析或基于单个术语的字段有意义.

② 使用params关键字: 每次使用时都必须加载和解析_source, 这是非常缓慢的.

建议: 使用doc关键字, 从文档中访问相关字段的值, 这种方式更加高效.

参考资料

ES 6.6 官方文档 - How to use scripts

版权声明

作者: 马瘦风(https://healchow.com)

出处: 博客园 马瘦风的博客(https://www.cnblogs.com/shoufeng)

感谢阅读, 如果文章有帮助或启发到你, 点个[好文要顶

ES 27 - Elasticsearch脚本的使用实践的更多相关文章

  1. ES 13 - Elasticsearch的元字段 (_index、_type、_source、_routing等)

    目录 1 标识元字段 1.1 _index - 文档所属的索引 1.2 _uid - 包含_type和_id的复合字段 1.3 _type - 文档的类型 1.4 _id - 文档的id 2 文档来源 ...

  2. ES 07 - Elasticsearch查询文档的六种方法

    目录 1 Query String Search(查询串检索) 2 Query DSL(ES特定语法检索) 3 Query Filter(过滤检索) 4 Full Text Search(全文检索) ...

  3. Linux(centos)安装es(elasticsearch)

    前提条件--需要安装jdk环境,不同版本的es所对应的jdk版本要求不同,es6的使用jdk1.8可以 1.下载elasticsearch压缩包 下载地址:https://www.elastic.co ...

  4. 编写Shell脚本的最佳实践

    编写Shell脚本的最佳实践 http://kb.cnblogs.com/page/574767/ 需要记住的 代码有注释 #!/bin/bash # Written by steven # Name ...

  5. ES 21 - Elasticsearch的高级检索语法 (包括term、prefix、wildcard、fuzzy、boost等)

    目录 1 term query - 索引词检索 1.1 term query - 不分词检索 1.2 terms query - in检索 2 prefix query - 前缀检索 3 wildca ...

  6. ES 32 - Elasticsearch 数据建模的探索与实践

    目录 1 什么是数据建模? 2 如何对 ES 中的数据进行建模 2.1 字段类型的建模方案 2.2 检索.聚合及排序的建模方案 2.3 额外存储的建模方案 3 ES 数据建模实例演示 3.1 动态创建 ...

  7. Elasticsearch 最佳运维实践 - 总结(一)

    对于Elasticsearch的学习,需要清楚的明白它的每个核心概念,由浅入深的了解,才能更好的掌握这门技术.下面先简单罗列下Elasticsearch的核心概念: 一.Elasticsearch数据 ...

  8. Elasticsearch索引容量管理实践【>>戳文章免费体验Elasticsearch服务30天】

    [活动]Elasticsearch Service免费体验馆>> Elasticsearch Service自建迁移特惠政策>>Elasticsearch Service新用户 ...

  9. ES 15 - Elasticsearch中的数据类型 (text、keyword、date、geo等)

    目录 1 核心数据类型 1.1 字符串类型 - string(不再支持) 1.1.1 文本类型 - text 1.1.2 关键字类型 - keyword 1.2 数字类型 - 8种 1.3 日期类型 ...

随机推荐

  1. c++学习书籍推荐《面向对象程序设计:C++语言描述(原书第2版)》下载

    百度云及其他网盘下载地址:点我 <面向对象程序设计:C++语言描述(原书第2版)>内容丰富,结构合理,写作风格严谨,深刻地论述了c++语言的面向对象编程的各种技术,主要内容包括:面向对象编 ...

  2. C#如何加载程序运行目录外的程序集 (转)

    ---恢复内容开始--- 尼玛,为了这个问题,纠结到差点吐出干血,赶紧记下来! 源地址:http://blog.csdn.net/dyllove98/article/details/9391325 我 ...

  3. 包教包会之Open Live Writer设置代码样式

    Open Live Writer(以下简称OLW),作为一个在本地写博文,然后发布到各个博客网站的客户端,在使用上个人觉得还是比较好用的.但是其对IT博文中代码部分的内容样式支持不是很友好.下面是本人 ...

  4. idea下maven命令打包不同配置

    1. 场景描述 不知道大家有没有遇到过?Idea集成的maven,在切换不同环境配置的时候,有时候反应很慢,还存在切换后打包还是原配置的情况. 2. 问题解决 通过在idea下执行maven命令进行切 ...

  5. 20190101.DDD笔记

    建立领域模型步骤 根据提供的信息完善主要业务场景和业务流程: 根据业务流程识别领域事件并按照时序排列: 针对领域事件进行命令识别: 针对领域事件和命令进行聚合和子域的初步识别: 在识别的subdoma ...

  6. Java虚拟机知识点【内存】

    运行时数据区 程序计数器(Program Counter)   每个线程独占自己的程序计数器.如果当前执行的方式不是native的,那程序计数器保存JVM正在执行的字节码指令的地址,如果是native ...

  7. Excel催化剂开源第7波-VSTO开发中Ribbon动态加载菜单

    在VS开发环境中,特别是VSTO的开发,微软已经现成地给开发者准备了设计器模式的功能区开发,相对传统的VBA.ExcelDna和其他方式的COM加载项开发来说,不需要手写xml功能区,直接类似拖拉窗体 ...

  8. 怎样在自己的网页中调用百度API

    https://blog.csdn.net/u010251278/article/details/52877370 以下内容转自上述网站,为了以后的学习方便,为此才特地将该网站内容转到自己的博客,多谢 ...

  9. win10 安装mysql(图文详情)避免卡在最后一步

    win10 安装mysql 本人安装mysql一般都是在镜像文件夹中下载(http://mirrors.sohu.com/),最近系统重做了之后安装mysql5.5.msi,可以安装成功.但是在最后的 ...

  10. [03] HEVD 内核漏洞之UAF

    作者:huity出处:https://www.cnblogs.com/huity35/p/11240997.html版权:本文版权归作者所有.文章在博客园.个人博客同时发布.转载:欢迎转载,但未经作者 ...