Elasticsearch 重新索引现有类型映射中的项目

Elasticsearch reindex items in existing type mapping

我向类型映射添加了一个新的 属性,我需要重新索引该类型的所有现有项目才能使用新的 属性。

我应该使用哪个 API 来执行此操作?

您必须使用 reindex api:首先您必须创建新索引,然后您可以使用 reidex api 将数据从源索引传输到新索引。

如果您要添加一个新字段,它以前在您的索引中不存在,您不需要重新索引,您只需使用 PUT 映射添加新字段 API http://nocf-www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-mapping.html

您在使用新字段更新映射之前创建的文档将不包含此新字段,因此搜索或聚合不会考虑此字段,它将作为缺失字段使用。

如果您需要在使用新字段类型的默认值搜索旧文档时考虑这个新字段,那么您需要重新索引。例如,如果您的新字段是整数类型,并且您明确需要将该字段包含在具有零值(默认值)的旧文档中,因为您想要计算有多少文档具有这个新字段 = 0,那么您需要重新索引,但是大多数用例我们可以将缺失的字段视为默认值,因此无需重新索引。

ElastiSearch (ES) 无法在映射中添加新字段并自动更新旧索引,即使由于 ES 存储数据的性质,新索引的默认值也是如此。 ES 使用不可变段来存储索引,因此当您更新文档时,ES 不会物理更新更改的字段,但它会创建一个用新数据更新的旧文档的新副本,并将旧文档标记为已删除,所以即使您更新文档中的一个简单字段,您也会得到文档的新版本,而旧版本被标记为已删除

另一种选择是在 Elasticsearch 中创建您的代码将引用的索引别名。如果您需要更改映射,您可以执行以下操作,这将允许很少甚至没有停机时间。

  • 使用更新的 ES 映射配置创建新索引
  • 使用重新索引api将数据复制到这个新索引
  • 删除旧的索引别名并用相同的名称重新创建它。

既然没有人愿意对这个长期存在的问题给出完整而明确的答案,我就去做吧:

# First of all: enable blocks write to enable clonage
PUT /my_index/_settings
{
  "settings": {
    "index.blocks.write": true
  }
}

# clone index into a temporary index
POST /my_index/_clone/my_index-000001  

# Copy back all documents in the original index to force their reindexetion
POST /_reindex
{
  "source": {
    "index": "my_index-000001"
  },
  "dest": {
    "index": "my_index"
  }
}

# Disable blocks write
PUT /my_index/_settings
{
  "settings": {
    "index.blocks.write": false
  }
}

# Finaly delete the temporary index
DELETE my_index-000001