首页 > 解决方案 > 将索引的映射从简单映射更新为对象映射

问题描述

嗨,我是 elasticsearch 7.9 更新映射的新手,我遇到了一个用例,我必须将一个简单的字段映射更新为一个对象映射,在我应用查询之前,我创建了一个简单的示例来测试我的目的,这就是我所拥有的作为初始索引映射:

{
  "myindex" : {
    "mappings" : {
      "properties" : {
        "flag" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

我想将字段名称标志更新为标记并向其中添加一个名为id的嵌套字段,该字段将包含初始索引myindex的字段标志的值,我执行了以下步骤:

  1. 使用以下映射创建了新索引mynewindex :
PUT mynewindex/_mapping
{
"properties" : {
        "tag" : {
          "properties": {
            "id" : {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword"
                }
              }
            }
          }
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword"
            }
          }
        }
      }
}
  1. 并使用重新索引 API:
POST _reindex
{
  "source": {
    "index": "myindex"
  },
  "dest": {
    "index": "mynewindex"
  },
  "script": {
    "source": "ctx._source.tag.id = ctx._source.remove(\"flag\")"
  }
}

这给了我这个错误:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "script_exception",
        "reason" : "runtime error",
        "script_stack" : [
          "ctx._source.tag.id = ctx._source.remove(\"flag\")",
          "               ^---- HERE"
        ],
        "script" : "ctx._source.tag.id = ctx._source.remove(\"flag\")",
        "lang" : "painless",
        "position" : {
          "offset" : 15,
          "start" : 0,
          "end" : 47
        }
      }
    ],
    "type" : "script_exception",
    "reason" : "runtime error",
    "script_stack" : [
      "ctx._source.tag.id = ctx._source.remove(\"flag\")",
      "               ^---- HERE"
    ],
    "script" : "ctx._source.tag.id = ctx._source.remove(\"flag\")",
    "lang" : "painless",
    "position" : {
      "offset" : 15,
      "start" : 0,
      "end" : 47
    },
    "caused_by" : {
      "type" : "null_pointer_exception",
      "reason" : "Cannot invoke \"Object.getClass()\" because \"callArgs[0]\" is null"
    }
  },
  "status" : 400
}

在 elastic doc中找到的无痛脚本,正如我所期望的点符号工作,任何建议或解决方法使其工作!

标签: elasticsearchelasticsearch-painless

解决方案


由于标签为空,它给出了空指针,你必须先创建一个地图。

下面应该工作

POST _reindex
{
  "source": {
    "index": "myindex"
  },
  "dest": {
    "index": "mynewindex"
  },
  "script" : {
    "source": """
        if(ctx._source.tag == null) {
          ctx._source.tag = new HashMap();
        }
        if(ctx._source.flag != null) {
          ctx._source.tag.id = ctx._source.remove("flag")
        }
      """,
    "lang": "painless"
  }
}

推荐阅读