https://blog.csdn.net/aiyaya_/article/details/79567091

前言
我们在使用ES的时候,尤其是初学者,通常都会遇到一个问题,那就是文档字段的映射类型创建错误问题,但是ES上却不能像mysql一样直接去修改字段类型,这时便出现了这个棘手的问题,今天让我们用一种索引重建的方式来修改字段映射类型,本文使用的ES是5.6.3版本。

前提
使用索引重建并且不停机,需要有个前提,那就是你在使用索引时,都是使用索引别名而不是使用真正的索引名 
,如果这点在你的程序上还没有做的话,那么请为其建立别名,好处很多,一旦当前索引出现了什么问题 不能及时恢复,你可以紧急切换到备用索引上而无需再重启服务、方便索引重建等等。

思路
说下我们索引重建的思路,假设我们现有索引名为:a_v1,代表索引a的第一个版本,其别名为索引:a,重建步骤如下: 
第一步:创建索引a_v2(该索引的mapping需要与a_v1基本保持一致,除了你要修改的字段mapping) 
第二步:把a_v1的数据导入a_v2索引中(ES中有现成的语句支持) 
第三步:把a_v1别名删除并且同时为a_v2添加别名a(此时线上程序已经切换到a_v2数据源上了) 
第四步:再次执行第二步骤,目的是增量同步a_v1中修改但没有同步到a_v2中的数据(因为你在做第二、三步的时候很可能线上的a_v1索引数据发生修改了)

举例说明
下面我们以商品的索引重建为例,来看下具体的语句要怎么写吧O(∩_∩)O~,假设现在已经有索引goods_v1别名为goods

1. 新建目标索引V2版本
curl -XPUT --header 'Accept: application/json' 'http://es.zhuma.com/goods_v2' -d '{
        "mappings": {
            "default": {
                "dynamic": "false",
                "properties": {
                    "id": {
                        "type": "long"
                    },
                    "name": {
                        "type": "text",
                        "analyzer": "ik_max_word"
                    },
                    "desc": {
                        "type": "text",
                        "analyzer": "ik_max_word"
                    },
                    "quantity": {
                        "type": "integer"
                    }
                }
            }
        },
        "settings": {
            "index": {
                "number_of_shards": "5",
                "provided_name": "goods_v1",
                "max_result_window": "50000",
                "creation_date": "1521437794175",
                "analysis": {
                    "analyzer": {
                        "ik": {
                            "tokenizer": "ik_max_word"
                        }
                    }
                },
                "number_of_replicas": "1",
                "uuid": "L1FLoPmAQNiwJkpdH1KJwA",
                "version": {
                    "created": "5060399"
                }
            }
        }
}'

2. 现有索引数据导入目标索引
curl -XPOST --header 'Accept: application/json' 'http://es.zhuma.com/_reindex' -d '{
  "conflicts": "proceed",
  "source": {
    "index": "goods_v1"
  },
  "dest": {
    "index": "goods_v2",
    "op_type": "create",
    "version_type": "external"
  }
}'

备注

reindex会将一个索引的数据复制到另一个已存在的索引,但是并不会复制原索引的mapping(映射)、shard(分片)、replicas(副本)等配置信息,所以这也是为什么我们在第一步中创建了和源索引结构基本相同的目标索引的原因。
设置conflicts为proceed代表当复制数据时发生版本冲突时继续执行(默认设置在版本冲突时会中止了reindex进程)。
设置op_type为create是指在目标索引中创建丢失的文档,所有现有文件将导致版本冲突。
设置version_type为external就是指数据从源索引拷贝到目标索引的时候会同时拷贝上版本号字段,并更新目标索引中比源索引中更旧版本的文档。
这里说下该导入功能执行效率,线上一个索引的数据量在8w左右用时3秒多(其实跟你的索引的一个文档数据量也有关系,这里仅仅给个参考点)。
更详细的文档说明可参考 官网文档-Reindex API

3. 设置索引的别名
curl -XPOST --header 'Accept: application/json' 'http://es.zhuma.com/_aliases' -d '{
    "actions": [
        {"remove": {"index": "goods_v1", "alias": "goods"}},
        { "add": {"index": "goods_v2",  "alias": "goods"}}
    ]
}'

4. 再次执行导出v1至v2导入数据
--------------------- 
作者:筑码-井哥 
来源:CSDN 
原文:https://blog.csdn.net/aiyaya_/article/details/79567091 
版权声明:本文为博主原创文章,转载请附上博文链接!