【问题标题】:Update mapping of an index from a simple mapping to an object mapping将索引的映射从简单映射更新为对象映射
【发布时间】:2021-01-08 16:56:48
【问题描述】:

您好,我是 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
            }
          }
        }
      }
    }
  }
}

我想将字段名称 flag 更新为 tag 并向其添加一个名为 id 的嵌套字段,该字段将包含初始索引myindex的字段flag,我做了以下步骤:

  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
}

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

【问题讨论】:

    标签: elasticsearch elasticsearch-painless


    【解决方案1】:

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

    下面应该可以工作

    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"
      }
    }
    

    【讨论】:

    • 感谢您的回答!所以这意味着在elasticsearch中嵌套对象只是地图对象?表示tag的key为id,其值为id的值?
    • 再次感谢,您有与此用例或类似用例相关的任何文档吗?到目前为止我还没有找到。例如,假设我有这个映射:tag { id { time }} 意味着我们有 3 个级别的嵌套字段,在无痛的情况下,第一个 if 条件将是:if (ctx._source.tag == null) {ctx._source.tag = new HashMap();} if (ctx._source.tag.id == null) {ctx._source.tag.id = new HashMap();} if (ctx._source.tag.id.time == null) {ctx._source.tag.id.time = new HashMap();} 等等......然后在不为空时测试每个级别并且分配相应的值?
    • 我没有,但是内部实现是java,所以可以使用java内部方法
    猜你喜欢
    • 2019-05-27
    • 2019-09-19
    • 2019-06-23
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多