在操作ES的时,我们经常要对其所存的数据进行CRUD。那很多时候,我们会发现因为数据繁多,可能数据的类型没有及时发现进而已经被ES Dynamic Mapping了。但是我们知道,在ES里,Mapping一旦设定,field字段等信息是不能修改的。那我们总不至于把索引都删除了,再来重新弄吧,对吧,那么有没有一种高可用的方法能实现Mapping信息的更改呢?下面我来帮你解决这个问题:
ES 版本:6.8.2
模拟若干数据:我先给自己的索引里边加几条数据,如下:
我加了数据后,我后面发现,这个title的字段类型默认是"date",类型,而我原来的本意是要设置为String或者text类型。
通过这个命令查看: GET /hezhen_index/_mapping/my_type,结果如下:
那既然这个类型不对,那可以修改不?尝试修改:
报错如下:
所以,Mapping一旦设定,field字段是不能修改的。因此,我们唯一的办法,就是reindex。也就是说,重新建立一个索引。将旧索引的数据查询出来导入新索引。步骤如下:
步骤如下:
1,给现有的旧的索引,建一个别名:
PUT /hezhen_index/_alias/goods_index
2,重新建一个新索引,并更改原来你需要改的字段的类型:
这个时候,我们已经建立一个新 的索引,并将新的字段的类型更改为自己想要的那个类型,对吧,接下来,我们将原旧的Index力的数据导入新的索引里边。我们使用scroll API。我们知道scroll api是es里进行海量数据滚动查询的。它能一批一批的查找数据,直到所有的数据处理完毕。那么我们来查一下:
结果我就查找到了一批数据,对吧。我们将这批数据假定量比较大,接下来,我们使用/_bulk接口将这批数据导入新的 index。_bulk接口是es下专门用来进行批量操作的接口。使用如下命令:
我们可以使用这个命令查看数据有没有进入到新的index.
GET /hezhen_index_new/_search
那么我们再接下来看看这个new index的字段有没有更改呢??
使用这个命令: GET /hezhen_index_new/_mapping/my_type
发现我们的字段已经更改了,数据也导入进去了,对吧,那么我们怎么切换这2个index呢?我们不至于要让正在使用的旧的Index进行停机吧??或者说让用户先不用吧,对吧。为了保证服务的高可用,我们采用如下方法:
先移除原来的Index,然后将index实时切换到new index.client客户端的透明切换
从这个命令我们可以看到,我们的Index已经平滑切换到hezhen_index_new上来了,但是客户使用的还是goods_index.
那我们的goods_index上有没有新的数据呢?
GET /goods_index/my_type/_search
发现我们的数据都来了
GET /goods_index/_mapping/my_type
同时,我们往新索引加一条数据,再通过别名再索引,看看能否正常。
发现也是成功的。那么这个试验是成功的。