es中painless脚本的使用

494 阅读1分钟

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时如下图: 在这里插入图片描述