Elasticsearch:尝试在 ctx._source 中循环嵌套的 params.value 给出 null_pointer_exception

Elasticsearch: Trying to loop a nested params.value in ctx._source gives null_pointer_exception

我正在尝试 运行 在 Kibana 中执行以下操作 elasticsearch-script:

{
  "script": {
      "source": "for( nested in ctx._source.params.title_type){if (nested.id == params.id){ nested.title = params.new_title}}",
      "lang": "painless",
      "params": {
          "title_type": "categories",
          "id": "123",
          "new_title": "new title"
      }
  }
}

为了将字段 source.categories.title 更新为“新标题”,如果 source.categories.id = “123”。

然而,当我尝试这样做时,出现以下错误:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "illegal_argument_exception",
        "reason" : "failed to execute script"
      }
    ],
    "type" : "illegal_argument_exception",
    "reason" : "failed to execute script",
    "caused_by" : {
      "type" : "script_exception",
      "reason" : "runtime error",
      "script_stack" : [
        "for( nested in ctx._source.params.title_type){",
        "                                 ^---- HERE"
      ],
      "script" : "for( nested in ctx._source.params.title_type){if (nested.id == params.id){ nested.title = params.new_title}}",
      "lang" : "painless",
      "caused_by" : {
        "type" : "null_pointer_exception",
        "reason" : null
      }
    }
  },
  "status" : 400
}

如果我将 'params.title_type' 替换为硬编码的 'categories',这个脚本就可以正常工作,就像这个例子中的那样:

{
  "script": {
      "source": "for( nested in ctx._source.categories){if (nested.id == params.id){ nested.title = params.new_title}}",
      "lang": "painless",
      "params": {
          "title_type": "categories",
          "id": "123",
          "new_title": "new title"
      }
  }
}

在第一个示例中,我在使用参数(就像我在脚本中的其他地方成功执行的操作一样)时做错了什么?

ctx._source下面是一个Map,所以你需要用不同的方式引用params.title_type,这样就可以了

ctx._source[params.title_type]

这相当于写作

ctx._source["categories"]

ctx._source.categories