部分更新 Elasticsearch 索引时出现 NPE

NPE when partially updating Elasticsearch Index

我正在按照 here 上的示例使用 Elasticsearch 中的部分更新来更新一组标签。

以下是我的脚本:

{
  "script": {
    "lang": "painless",
    "inline": "ctx._source.deviceTags.add(params.tags)",
    "params": {
      "tags": "search"
    }
  }
}

请求URL是:

https://aws-es-service-url/devices/device/123/_update

但我收到以下回复:

{
    "error": {
        "root_cause": [
            {
                "type": "remote_transport_exception",
                "reason": "[fBaExM8][x.x.x.x:9300][indices:data/write/update[s]]"
            }
        ],
        "type": "illegal_argument_exception",
        "reason": "failed to execute script",
        "caused_by": {
            "type": "script_exception",
            "reason": "runtime error",
            "script_stack": [
                "ctx._source.deviceTags.add(params.tags)",
                "                                 ^---- HERE"
            ],
            "script": "ctx._source.deviceTags.add(params.tags)",
            "lang": "painless",
            "caused_by": {
                "type": "null_pointer_exception",
                "reason": null
            }
        }
    },
    "status": 400
}

知道我做错了什么吗?

因为你的 deviceTags 数组最初是空的,你有两种方法来解决这个问题

一个。使用 upsert 确保 deviceTags 一开始就添加到您的文档中

{
  "script": {
    "lang": "painless",
    "inline": "ctx._source.deviceTags.add(params.tags)",
    "params": {
      "tags": "search"
    }
  },
  "upsert": {
    "deviceTags": ["search"]
  }
}

乙。保护您的代码免受 NPE

{
  "script": {
    "lang": "painless",
    "inline": "(ctx._source.deviceTags = ctx._source.deviceTags ?: []).add(params.tags)",
    "params": {
      "tags": "search"
    }
  }
}