ELK,萌萌哒

es7.8 reindex 修改字段类型(long 类型 reindex 成 keyword 类型)

Elasticsearch | 作者 hapjin | 发布于2021年03月16日 | 阅读数:4204

我有一个ES旧索引source_index,它的 mapping 结构中 字段 custom.serial_number 是 long 类型,现在我想通过 reindex 的方式把该字段修改成 keyword 类型,并且不影响此字段的查询(等值查询)
旧索引的 mapping 结构如下:可以看出:custom.serial_number 是 long 类型的。


     "mappings": {
    "date_detection": true,
    "numeric_detection": true,
    "properties": {
      "createTime": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "custom": {
        "properties": {
          "groupID": {
            "type": "keyword"
          },
          "projectID": {
            "type": "keyword"
          },
          "serial_number": {
            "type": "long"
          },
          "upload_time": {
            "type": "date"
          }
        }
      },
      "extra": {
        "type": "keyword",
        "index": false,
        "doc_values": false
      }
    }


一条示例数据如下(隐去了部分数据,但是不影响查看):

bug.png

 
我新建了一个新索引dest_index,把字段 custom.serial_number 类型设置成 keyword,mapping结构的其他设置完全与 source_index 相同。然后,参考文章:Convert the long datatype field to string,采用 _reindex 命令再配合 script 来进行数据reindex:


POST _reindex?pretty
{
  "source": {
    "index": "source_index"
  },
  "dest": {
    "index": "dest_index"
  },
  "script": {
    "source": "ctx._source.custom.serial_number = String.valueOf(ctx._source.custom.serial_number)"
  }
}


发现报错如下:


       "root_cause" : [
      {
        "type" : "script_exception",
        "reason" : "runtime error",
        "script_stack" : [
          "ctx._source.custom.serial_number = String.valueOf(ctx._source.custom.serial_number)",
          "                                                                    ^---- HERE"
        ],
        "script" : "ctx._source.custom.serial_number = String.valueOf(ctx._source.custom.serial_number)",
        "lang" : "painless",
        "position" : {
          "offset" : 68,
          "start" : 0,
          "end" : 83
        }
      }
    ]


错误的原因可能是:custom.serial_number 属于 object field type,有可能 script source 不支持 “多层级引用”custom.serial_number (个人猜测)
 
另外,我执行如下 reindex 命令,是可以成功的。


POST _reindex?pretty
{
  "source": {
    "index": "source_index"
  },
  "dest": {
    "index": "dest_index"
  },
  "script": {
    "source": "ctx._source.serial_number = String.valueOf(ctx._source.serial_number)"
  }
}


但是 mapping 结构变化了(额外多了一个 serial_number 字段,但是我要的是 custom.serial_number),不符合要求。
 
我参考了 ES 官方文档 How to use scripts,但是未找到答案,求大神解答,感激不尽。
 
已邀请:

hapjin

赞同来自:

Charele - Cisco4321

赞同来自:

你那个不算解决办法吧。
有的时候script是必须的。
 
我试了一下,是可以的啊。我用的是7。10。2
{
  "source": {
    "index": "a"
  },
  "dest": {
    "index": "b"
  }
,
  "script": {
    "source": "ctx._source.ages.age1= String.valueOf(ctx._source.ages.age1)"
  }
}
age1这个在a里面是long类型的,到了b就是keyword类型的
 
你不要事先建dest索引试下呢

要回复问题请先登录注册