You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Painless脚本实现嵌套字段count值的动态增减?

Elasticsearch Painless 动态嵌套字段累加与创建实现

完整可运行脚本

POST test/_update/3
{
  "script": {
    "source": """
      void processNestedMap(Map source, Map paramsMap) {
        for (Map.Entry entry : paramsMap.entrySet()) {
          String key = entry.getKey();
          Object value = entry.getValue();
          
          if (value instanceof Map) {
            if (!source.containsKey(key)) {
              source.put(key, new HashMap());
            }
            processNestedMap((Map)source.get(key), (Map)value);
          } else if (key == "count") {
            source.put(key, source.containsKey(key) ? source.get(key) + value : value);
          } else {
            source.put(key, value);
          }
        }
      }

      if (ctx._source.board_counts == null) {
        ctx._source.board_counts = new HashMap();
      }

      processNestedMap(ctx._source.board_counts, params.myCounts);
    """,
    "lang": "painless",
    "params": {
      "myCounts": {
        "inner":{
          "board1":{"count":5},
          "board2":{"count":4},
          "board3":{"temp":1,"temp2":3}
        },
        "outer":{
          "board1":{"count":5},
          "board10":{"temp":1,"temp2":3}
        }
      }
    }
  }
}

核心逻辑解析

  • 递归遍历嵌套层级:自定义processNestedMap函数处理所有层级的字段:
    • 遇到Map类型的参数值时,先检查目标对象中是否存在对应key,不存在则创建空HashMap,再递归进入下一层
    • 针对count字段:存在则累加参数值,不存在则直接设置初始值
    • 非count的普通字段直接赋值(可根据业务需求调整此逻辑)
  • 根字段初始化:先确保board_counts字段存在(不存在则创建空Map),避免后续递归操作报错

嵌套字段存在性检测要点

不能直接通过ctx._source.board_counts.inner == null这类跨层级判断(上层字段不存在时会抛出空指针异常),必须逐层校验:

  1. 先确认当前层级的父字段是存在且为Map类型
  2. 再检查当前层级字段是否存在
  3. 递归逻辑自动完成了这种逐层检测与动态创建的流程

内容的提问来源于stack exchange,提问作者Bujji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 11:26:11