一、前言

在 Elasticsearch 中,一旦创建索引,就不能更改现有字段的数据类型。如果您需要更改数据类型,则需要重新创建索引并使用新的数据类型。以下针对各种业务场景总结几种修改方法。

二、【方法一】删除重建

这种方式的使用场景为当前索引库数据量不大,而且可以及时同步数据到该索引库。一般用在实时采集数据到ES中,删除旧的索引后,重新采集数据即可。

delete /my_index

三、【方法二】使用备份数据重建

当你数据量也不算太大,_reindex的执行速度还算快的,几十万的数据量大概在十分钟以内,百万级的大概在半个小时内就可以完全备份,可以先使用备份库,具体思路如下:

1、获取源索引的数据(mapping) 并 创建临时索引:my_index_temp, 2、备份数据到临时索引:my_index_temp 3、删除原索引: my_index, 4、重新创建正确数据类型索引:my_index 5、再把临时索引:my_index_temp的数据备份到新创建索引 my_index。

操作步骤如下:

1、获取原索引

//获取源索引的mapping数据

GET my_index/_mapping

//返回示例如下

{"my_index": {

"mappings": {

"cdp_doc": {

"properties": {

"whyBuy": {

"type": "keyword"

},

"zipcode": {

"type": "keyword"

}

}

}

}

}

2、创建一个临时索引,并备份原索引的数据

//代码如下(示例):

//# 创建Mapping

PUT my_index_temp

{

"mappings": {

"cdp_doc": {

"properties": {

"whyBuy": {

"type": "keyword"

},

"zipcode": {

"type": "keyword"

}

}

}

}

}

3、备份原数据

// 同步数据值临时索引

POST _reindex?refresh&wait_for_completion=false

{

"conflicts": "proceed",

"source": {

"index": "my_index"

},

"dest": {

"index": "my_index_temp",

"op_type": "create"

}

}

//查询确认数据是否复制过去

GET my_index_temp/_search

{

"query": {

"term": {

}

}

}

4、删除原索引及数据

//删除索引及数据

delete my_index

5、重新创建正确的索引(注意是修改后的索引)

同步骤2

6、迁移旧数据回新索引

同步骤3

7、删除临时索引

同步骤4

四、【方法三】使用嵌套增加属性

这种方法针对索引字段类型text,添加keyword类型操作。

首先区分一下text类型和keyword类型:

text类型:会进行分词、分词后建立索引、支持模糊查询、不支持准确查询、不支持聚合查询。

keyword类型:不会分词、直接建立索引、不支持模糊查询、支持准确查询、支持聚合查询。

操作步骤如下:

PUT my_index/_mapping

{

"properties": {

"my_fields": {

"type": "text",

"analyzer": "ik_smart",

"fields": {

"keyword": {

"type": "keyword",

"ignore_above": 256

}

}

}

}

}

// 结果:

{

"acknowledged" : true

}

注意这里有个问题,如果直接执行完后,数据不会及时更新,所以执行到这里如果去聚合,旧数据是一样没有聚合到的,还需要执行以下语句更新数据

POST my_index/_update_by_query

# 后台执行

POST my_index/_update_by_query?wait_for_completion=false

修改完成之后,新的数据就会按照新的mapping来走了,可以通过my_fields.keyword的形式进行完全匹配和聚合搜索。

五、【方法四】使用数据从原索引导入新索引中

假设您要将一个名为 my_index 的索引中的整数类型更改为字符串类型。以下示例代码将源索引中的数据复制到新索引中,并使用新的字段映射规则:

POST _reindex

{

"source": {

"index": "my_index"

},

"dest": {

"index": "my_new_index"

},

"script": {

"source": "ctx._source.my_integer_field = ctx._source.my_integer_field.toString()",

"lang": "painless"

},

"mappings": {

"properties": {

"my_integer_field": {

"type": "text"

}

}

}

}

在上面的代码中,我们使用脚本将原始索引中的整数类型字段 my_integer_field 转换为字符串类型,并将其保存到新的索引中。同时,在新索引中定义了一个新的数据类型 text,用于存储该字段。

切换到新的索引

最后,一旦新索引准备就绪并包含原始索引的所有数据,就可以切换应用程序以使用新的索引。

需要注意的是,重新创建索引可能会导致数据丢失或不可用性。在执行此操作之前,请务必备份和验证数据。

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: