⼀般在以下⼏种情况时,我们需要重建索引:
- 索引的 Mappings 发⽣变更:字段类型更改,分词器及字典更新
- 索引的 Settings 发⽣变更:索引的主分⽚数发⽣改变
- 集群内,集群间需要做数据迁移
Elasticsearch 提供如下两种内置 API 可实现上述索引重建:
- Update By Query:在现有索引上重建
- Reindex:在其他索引上重建索引
1. Update By Query
相关阅读:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/docs-update-by-query.html
ES 支持对 mapping 修改增加子字段,比如下述文档中对 content
字段增加 text 类型的子字段 english
,并指定英文分词器:
1 | PUT blogs/_mapping |
默认情况下,采用上述更新之前已经存入的文档并不存在子字段 english
的相关定义(当然更新之后加入的文档没有此问题)。例如在做上述更新之前已经通过如下语句添加了一篇文档:
1 | PUT blogs/_doc/1 |
因此下面通过子字段去查询时,是无法查询到相关信息的。
1 | POST blogs/_search |
为了解决这种问题,可以使用如下 _update_by_query
来同步 mapping 上的更新到所有文档上。再次使用上述查询语句我们便能查询到相关文档信息:
1 | POST blogs/_update_by_query |
2. Reindex
相关阅读:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/docs-reindex.html
由于 ES 不允许在原有 Mapping 上对字段类型进⾏修改,因此只能创建新的索引,并且设定正确的字段类型,再重新导⼊数据。
Reindex API ⽀持把⽂档从⼀个索引拷⻉到另外⼀个索引,在如下的一些场景可以使用 Reindex API:
- 修改索引的主分⽚数
- 改变字段的 Mapping 中的字段类型
- 集群内数据迁移 / 跨集群的数据迁移
需要注意的是使用 reindex 进行字段类型变更到操作时,需要先自行创建新索引的 mapping 后在进行 reindex。例如下面新建索引 blogs_fix 及其 mapping,不同于 blogs 索引,keyword 字段没有子字段,而是只定义其类型。我们使用 reindex 实现将 blogs 中的数据导入的 blogs_fix 中并以新的 mapping 来存储数据:
1 | PUT blogs_fix |
另外,可以通过指定 op_type
参数值为 create
来控制 reindex 只对未创建的目标索引有效。当 dest 指定的索引已经存在数据时,不支持使用 reindex 。