Elasticsearch重建索引

为什么要重建索引

众所周知, es是一种高效的数据查询,检索引擎。 可以对海量的数据进行快速的查询。但是在使用es的时候,经常会遇到一个比较尴尬的问题,那就是es索引里的字段类型是固定的,不可修改的。而es的索引又是可以自动扩展字段的。 这个时候自动扩展出来的字段就是使用了默认的字段类型(通常是text类型)。

惊不惊喜!

查看索引字段的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
GET /my_index

{
"my_index":{
"mappings":{
"_doc":{
"dynamic_templates":[
{
"string_fields":{
"match_mapping_type":"string",
"mapping":{
"type":"keyword"
}
}
}
],
"properties":{
"field_a":{
"type":"keyword"
},
"field_b":{
"type":"date",
"format":"yyyy-MM-dd HH:mm:ss"
},
"field_c":{
"type":"text",
"norms":false,
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
}
}
}
}
}
}
}

聪明的你肯定想到了, 如果我们忘记加字段了, 或者字段加错了要修改字段类型咋办? 这个时候场景的办法就只有一个了:

重建索引!

从数据库角度来看,也就是新增新表, 迁移数据, 删除老表.

背景 与 目标

Elasticsearch 版本 : v 6.6
目标: 在my_index 索引上新增一个integer字段. 且中间不间断服务.

S1: 使用别名代替实体索引

使用aliases api
创建一个别名my_index 指向实际的索引my_idex.
这样,我们通过my_index访问数据时, 就不会直接访问my_index索引了, 而是通过别名指向对应的索引.

1
2
3
4
5
6
POST /_aliases
{
"actions" : [
{ "add" : { "index" : "my_index", "alias" : "my_index" } }
]
}

S2: 创建新的索引

使用 put mapping api
打算新增一个字段 fiedl_d, 数据类型.

因为默认的string类型是keyword (假设, 意会即可), 所以如果想要新增一个整型类型, 就不能通过自动的扩展字段使用默认类型的方式. 所以必须显式的指定字段类型.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
put my_index2

{
"_doc":{
"dynamic_templates":[
{
"string_fields":{
"match_mapping_type":"string",
"mapping":{
"type":"keyword"
}
}
}
],
"properties":{
"field_a":{
"type":"keyword"
},
"field_b":{
"type":"date",
"format":"yyyy-MM-dd HH:mm:ss"
},
"field_c":{
"type":"text",
"norms":false,
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
}
},
"field_d":{
"type":"integer"
}
}
}
}

S3: 迁移数据

使用 Reindex api
将老的my_index 数据迁移到新的my_index2上.
这一步比较耗时, 做好心理准备.

1
2
3
4
5
6
7
8
9
POST _reindex
{
"source": {
"index": "my_index"
},
"dest": {
"index": "my_index2"
}
}

S4: 变更别名

使用aliases api
将别名从老的index, 指向新的index

1
2
3
4
5
6
7
POST /_aliases
{
"actions" : [
{ "remove" : { "index" : "my_index", "alias" : "my_index" } },
{ "add" : { "index" : "my_index2", "alias" : "my_index" } }
]
}

S5: 将老索引的增量数据迁移到新索引上

处理迁移期间my_index 发生的增量数据

1
2
3
4
5
6
7
8
9
10
11
POST _reindex
{
"size": 10000,
"source": {
"index": "my_index",
"sort": { "date": "desc" }
},
"dest": {
"index": "my_index2"
}
}

S6: 删除老索引

使用 delete api

1
delete my_index

总结

至此, 整个重建索引过程完毕.
很麻烦吧.
为了不这么麻烦, 以后要给es 增加新字段时, 一定要先通过maping的方式先新增字段. 然后再在代码里处理相对应的逻辑.

over!

补充说明

可以通过put mapping的方式, 增量补充索引的字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
PUT my_index
{
"mappings": {
"_doc": {
"properties": {
"manager": {
"properties": {
"age": { "type": "integer" },
"name": { "type": "text" }
}
},
"employees": {
"type": "nested",
"properties": {
"age": { "type": "integer" },
"name": { "type": "text" }
}
}
}
}
}
}

参考

官方文档-api
官方文档-api2


Elasticsearch重建索引
https://www.hancher.top/2022/09/12/es-reindex/
作者
寒澈
发布于
2022年9月12日
许可协议