淘先锋技术网

首页 1 2 3 4 5 6 7

 

概述

Elasticsearch 的 mapping 在创建 indices 时即已确定,无法更改。那么,当我们需要更新 mapping 时,该如何是好呢?

基本思路
当我们在创建一条索引时,添加好 mapping 后,可设置一个 alias 指向该索引,然后生产环境采用该 alias 来索引数据。当然,如果没有这样做的话,建议趁早备份,修改 API 。

既然已创建的 indices 无法修改,我们可以重新创建一个新的 indices, 然后将原 indices 上的数据复制到新的 indices 上,再将 alias 指向新 indices。最后,删除原索引。

参数说明


当前索引名称: myindex_v1
生产索引名称:myindex
目标索引名称: myindex_v2

 

操作步骤

旧库的mapping结构

GET /myindex_v1/_mapping

需求:我们需要把上面的text转化为keyword类型

第一步:创建旧库索引别名

#增加别名
POST /_aliases
{
    "actions" : [
        { "add" : { "index" : "myindex_v1", "alias" : "myindex" } }
    ]
}

第二步:创建新索引mapping

PUT /myindex_v2
{
  "_all": {
    "enabled": false
  },
  "mappings": {
    "doc": {
      "dynamic_templates": [
        {
          "string_as_keyword": {
            "match_mapping_type": "string",
            "mapping": {
              "type": "keyword"
            }
          }
        }
      ],
      "properties": {
        "age": {
          "type": "integer"
        },
        "sale": {
          "type": "double"
        },
        "date": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        }
      }
    }
  }
}

第三步:复制数据

#复制数据
POST /_reindex
{
    "source": {
        "index": "myindex_v1"
    },
    "dest": {
        "index": "myindex_v2"
    }
}

注意:如果数据量超大的话,复制数据所消费的时间比较多,所以请在构建索引前尽量考虑周全。

reindex方案请参考下面的连接

 https://www.cnblogs.com/Ace-suiyuan008/p/9985249.html

POST  _reindex?slices=5&refresh&wait_for_completion=false
{
  "conflicts": "proceed",
  "source": {
    "index": "poc",
    "type": "doc", 
    "size": 5000,
    "_source":["CUSTNAME","CUSTNO","CUSTPHONE","ALARMLEVEL"]
  },
  "dest": {
    "index": "new_twitter",
    "op_type": "create",
    "routing": "=cat"
  },
  "script": {
    "source": "ctx._source.custname = ctx._source.remove(\"CUSTNAME\");ctx._source.custno = ctx._source.remove(\"CUSTNO\");ctx._source.custphone = ctx._source.remove(\"CUSTPHONE\");ctx._source.alarmlevel = ctx._source.remove(\"ALARMLEVEL\")"
  }
}

复制数据比较快速的是根据分片数来复制,slices最好是ES的分片数的一倍或者整数倍(一倍最佳)。

wait_for_completion=false 快速返回一个任务ID,不需要等待复制执行完毕。

ctx._source.custname = ctx._source.remove(\"CUSTNAME\")  标识将原有字段中的CUSTNAME 修改为目标库中custname,修改多个字段使用分号分割

"size": 5000  表示每次拉取对的数量,此处根据你的环境调整

执行结果为

{
   "task" : "Wv72OosPRIe3aDwcOzXWrg:8241018"
}

可以根据执行task查询当前任务执行情况

GET /_tasks/Wv72OosPRIe3aDwcOzXWrg:8241018

返回结果

{
  "completed" : true,
  "task" : {
    "node" : "Wv72OosPRIe3aDwcOzXWrg",
    "id" : 8241018,
    "type" : "transport",
    "action" : "indices:data/write/reindex",
    "status" : {
      "total" : 829162,
      "updated" : 0,
      "created" : 829162,
      "deleted" : 0,
      "batches" : 170,
      "version_conflicts" : 0,
      "noops" : 0,
      "retries" : {
        "bulk" : 0,
        "search" : 0
      },
      "throttled_millis" : 0,
      "requests_per_second" : -1.0,
      "throttled_until_millis" : 0,
      "slices" : [...]
    },
    "description" : """reindex from [poc][doc] updated with Script{type=inline, , idOrCode='ctx._source.custname = ctx._source.remove("CUSTNAME");ctx._source.custno = ctx._source.remove("CUSTNO");ctx._source.custphone = ctx._source.remove("CUSTPHONE");ctx._source.alarmlevel = ctx._source.remove("ALARMLEVEL")', options={}, params={}} to [new_twitter]""",
    "start_time_in_millis" : 1606897630282,
    "running_time_in_nanos" : 34318304260,
    "cancellable" : true,
    "headers" : { }
  },
  "response" : {
    "took" : 34317,
    "timed_out" : false,
    "total" : 829162,
    "updated" : 0,
    "created" : 829162,
    "deleted" : 0,
    "batches" : 170,
    "version_conflicts" : 0,
    "noops" : 0,
    "retries" : {
      "bulk" : 0,
      "search" : 0
    },
    "throttled" : "0s",
    "throttled_millis" : 0,
    "requests_per_second" : -1.0,
    "throttled_until" : "0s",
    "throttled_until_millis" : 0,
    "slices" : [...],
    "failures" : [ ]
  }
}

completed 表示是否执行完毕

response 有具体执行的情况

第四步:移除旧库添加新库

#移除旧库添加新库
POST /_aliases
{
    "actions": [
        { "remove" : { "index" : "myindex_v1", "alias" : "myindex" } },
        { "add" : { "index" : "myindex_v2", "alias" : "myindex" } }
    ]
}

第五步:删除旧库(确认数据已经复制完毕)

#删除旧库
DELETE myindex_v1

第六步:检查新库

#查询
GET /myindex/_search


GET /myindex/_mapping

至此,更新mapping完成