es自6.0开始,es只支持painless,而painless的语法、函数等与java有很大的相似性,官网API说明:
这些方法中的大多数直接从 Java 运行时环境 (JRE) 中公开,而其他方法则是 Elasticsearch 或 Painless本身的一部分
官网API地址:www.elastic.co/guide/en/el…
script脚本使用示例
eg1:
GET order_20220715/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"@timestamp": {
"gte": 1657778280000,
"lte": 1657779240000,
"format": "epoch_millis"
}
}
}
] ,
"filter": [
{
"script": {
"script": {
"lang": "painless",
"source": """
# 获取文档返回的额message字段值,因为我的message为text字段,所以需要转成keyword格式
def message = doc['message.keyword'].value;
def str = message.indexOf(':');
def lonlat = message.substring((str + 1),message.length());
def sum = lonlat.indexOf(',');
def lon = lonlat.substring(0,sum);
def lat = lonlat.substring((sum + 1),lonlat.length());
def lond = Double.parseDouble(lon);
def latd = Double.parseDouble(lat);
(lond + latd) == 151.745259
"""
}
}
}
]
}
},
"_source": [
"TSF",
"message",
"traceId"
],
"sort": [
{
"TSF.keyword": {
"order": "asc"
}
}
]
}
在"filter"中是过滤,即只返回符合条件的值; 与query平级则是处理结果,不论符不符合都返回。
eg2:
自定义pipeline,根据开始时间和结束时间计算时间差,并且修改到文档里的”stayTime“字段。
PUT /_ingest/pipeline/time_pipline
{
"processors": [
{
"script": {
"lang": "painless",
"source": """
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("Asia/Shanghai"));
String rlTime = ctx['recordLastTime'];
ZonedDateTime rlZdt = ZonedDateTime.parse(rlTime, fmt);
long rlTimestamp = rlZdt.toInstant().toEpochMilli();
String rfTime = ctx['recordFirstTime'];
ZonedDateTime rfZdt = ZonedDateTime.parse(rfTime, fmt);
long rfTimestamp = rfZdt.toInstant().toEpochMilli();
long diff = rlTimestamp - rfTimestamp;
ctx['stayTime'] = diff;
"""
}
}
]
}
在调用pipeline时如下图: