Elasticsearch 中 Painless 脚本详解

时间:2024-09-29 16:39:54

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 增加字段_戴国进的博客-****博客