1、什么是 painless?
ElasticStack在升级到5.0版本之后,带来了一种内置的新型脚本语言:painless。painless针对Elasticsearch的场景来进行优化,只做Elasticsearch数据的操作,更加轻量级,速度要快好几倍,并且支持Java静态类型,语法保持Groove类似,还支持Java的lambda表达式。painless脚本分为两种类型:inline script 和 stored script。前者仅仅写在api请求中,后者可以存储起来。如同sql和存储过程的区别。本文将全面介绍Painless语法,包括变量、表达式、控制流、函数等方面的内容。
2、painless语法模式
"script": {
"lang": "...", (1)
"source" | "id": "...", (2)
"params": { ... } (3)
}
(1)写入脚本的语言,默认为painless。
(2)脚本可以指定为 source 或者 id。inline script 使用 source ;而 stored script 使用 id。
(3)传递给脚本的命名参数。
3、painless变量
Painless支持多种类型的变量,包括整数、浮点数、字符串、布尔值等。变量在使用前需要进行声明和初始化。
声明变量
可以使用关键字def来声明一个变量,并且可以根据需要显式指定变量的类型。
def count = 10; // 整数类型
def price = 19.99; // 浮点数类型
def name = "John"; // 字符串类型
def isAvailable = true; // 布尔值类型
修改变量值
变量的值可以随时进行修改,并且可以根据需要改变变量的类型。
count = 20; // 修改整数类型变量
price = 29.99; // 修改浮点数类型变量
name = "Mike"; // 修改字符串类型变量
isAvailable = false; // 修改布尔值类型变量
4、painless表达式
Painless支持常见的数学和逻辑运算符,并且可以使用括号来改变运算的优先级。
数学运算
Painless支持加法、减法、乘法和除法等数学运算。
def a = 5;
def b = 3;
def c = a + b; // 加法
def d = a - b; // 减法
def e = a * b; // 乘法
def f = a / b; // 除法
逻辑运算
Painless支持与、或和非运算。
def a = true;
def b = false;
def c = a && b; // 与运算
def d = a || b; // 或运算
def e = !a; // 非运算
5、painless控制流
Painless支持条件语句和循环语句,可以根据不同的条件执行不同的代码块。
条件语句
条件语句用于根据不同的条件选择性地执行代码。Painless支持if-else语句和switch语句。
if-else语句
if-else语句根据给定的条件判断是否执行某个代码块。
def score = 80;
if (score >= 60) {
println("及格");
} else {
println("不及格");
}
switch语句
switch语句根据给定的变量的值执行不同的代码块。
def dayOfWeek = 3;
switch (dayOfWeek) {
case 1:
println("星期一");
break;
case 2:
println("星期二");
break;
case 3:
println("星期三");
break;
default:
println("其他");
break;
}
循环语句
循环语句用于重复执行某个代码块。Painless支持for循环和while循环。
for循环
for循环用于指定一个变量的初始值、循环条件和每次循环后更新的操作。
for (def i = 0; i < 5; i++) {
println(i);
}
while循环
while循环在每次循环前检查条件是否满足,满足则执行代码块。
def i = 0;
while (i < 5) {
println(i);
i++;
}
6、painless数组和集合
Painless支持数组和集合的操作,包括创建、访问和修改元素等。
数组
Painless使用方括号[]来表示一个数组,并且可以使用索引来访问和修改数组中的元素。
def numbers = [1, 2, 3, 4, 5]; // 创建数组
def firstElement = numbers[0]; // 访问第一个元素
numbers[0] = 10; // 修改第一个元素的值
集合
Painless支持两种类型的集合:列表(List)和映射(Map)。列表是一组有序的元素,而映射是一组键值对。
def list = ["apple", "banana", "orange"]; // 创建列表
def map = ["name": "John", "age": 20]; // 创建映射
7、painless函数
Painless内置了许多常用的函数,可以用于字符串操作、数学运算、日期处理等。
字符串函数
Painless提供了许多用于字符串操作的函数,如length()、substring()和replace()等。
def str = "Hello World";
def len = str.length(); // 获取字符串长度
def substring = str.substring(0, 5); // 截取子字符串
def replaced = str.replace("World", "Painless"); // 替换字符串
数学函数
Painless提供了许多常用的数学函数,如abs()、sqrt()和ceil()等。
def num = -5.5;
def absNum = Math.abs(num); // 获取绝对值
def sqrtNum = Math.sqrt(num); // 开平方根
def ceilNum = Math.ceil(num); // 向上取整
日期函数
Painless支持处理日期和时间的函数,如now()、dayOfMonth()和format()等。
def now = new Date();
def dayOfMonth = now.dayOfMonth(); // 获取日期的天数
def formattedDate = now.format("yyyy-MM-dd"); // 格式化日期
参考:
How to write scripts | Elasticsearch Guide [8.10] | Elastic
Elasticsearch黑鸟教程30:painless脚本简介 - MyBatis中文官网
【Elasticsearch】Elasticsearch 在 Date Histogram Aggregation 中使用 painless 转换时间的时间进行统计直方图_馍 馍的博客-****博客
Elasticsearch:如何在 Elasticsearch 中轻松编写 Painless 脚本_painless脚本_Elastic 中国社区官方博客的博客-****博客
ES修改索引mapping - 简书
es elasticsearch 新增字段 field 并设置值_es新增字段并赋值_天道988的博客-****博客
ElasticSearch 7.4.0 mapping新增字段并赋值_elasticsearch update 增加字段_戴国进的博客-****博客