Elasticsearch重建索引

2022/09/12 编程技巧 Elasticsearch 共 2157 字,约 7 分钟

为什么要重建索引

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

惊不惊喜!

查看索引字段的方法:

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索引了, 而是通过别名指向对应的索引.

POST /_aliases
{
    "actions" : [
        { "add" : { "index" : "my_index", "alias" : "my_index" } }
    ]
}

S2: 创建新的索引

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

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

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上. 这一步比较耗时, 做好心理准备.

POST _reindex
{
  "source": {
    "index": "my_index"
  },
  "dest": {
    "index": "my_index2"
  }
}

S4: 变更别名

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

POST /_aliases
{
    "actions" : [
        { "remove" : { "index" : "my_index", "alias" : "my_index" } },
        { "add" : { "index" : "my_index2", "alias" : "my_index" } }
    ]
}

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

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

POST _reindex
{
  "size": 10000,
  "source": {
    "index": "my_index",
    "sort": { "date": "desc" }
  },
  "dest": {
    "index": "my_index2"
  }
}

S6: 删除老索引

使用 delete api

delete my_index

总结

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

over!

补充说明

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

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

文档信息

Search

    Table of Contents