关于 elasticsearch-reindex
此技能通过 elastic CLI 使用 Elasticsearch 的 reindex 功能复制索引或数据流中的文档,适用于迁移和筛选式复制。它要求预先准备目标映射,并支持远程复制、异步任务跟踪及目标数量验证。
主要功能
- 01复制索引或数据流文档
- 02按查询条件筛选源文档
- 03复制前创建目标映射
- 04异步运行并跟踪复制任务
- 05核对目标文档数量
适用场景
- 01将旧索引迁移到新映射索引
- 02只复制指定日期范围的文档
- 03在不同集群间迁移数据
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ elastic/ agent-skills --skill elasticsearch-reindex安装后在 Claude Code 中输入/elasticsearch-reindex确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-reference.mdpatterns.mdtroubleshooting.mdtuning.md详细介绍
Elasticsearch 重新索引
使用 POST /_reindex 将文档从源索引或数据流复制到目标。成熟的重新索引工作流会显式准备目标,选择本地或远程执行方式,仅在需要部分数据时于源端进行筛选,以异步方式运行耗时的复制任务,跟踪任务直至完成,并在报告结果前核实目标文档数。
环境配置
此技能通过 elastic CLI 执行 Elasticsearch 操作。如果尚未安装
elastic CLI,请告知用户其用途。不要猜测凭据、直接调用 HTTP API,也不要尝试其他变通方法。
此技能以 HTTP 简写形式引用操作(例如 GET /、GET /_cat/indices、GET /{index}/_mapping、
GET /{index}/_settings/index.mode、POST /_query)。本文末尾的 Operations 表格将每个简写映射到对应的 elastic CLI 命令——始终使用 CLI,不要直接调用 HTTP API。
流程
-
确认连接状态和部署类型。 调用
GET /。读取build_flavor和version.number,以判断是否支持分片、副本和集群设置 API(Serverless 在内部管理分片和副本,并会阻止大多数_cluster/*API)。判断标准:仅当集群可访问时才继续。如果调用失败,请停止操作——不要猜测端点或凭据。 -
确定使用本地还是远程重新索引。 比较源和目标所在的位置。
- 同一集群 — 使用本地重新索引:仅设置
source.index和dest.index。如果两个索引都位于当前连接的集群上,不要添加source.remote。 - 不同集群 — 使用远程重新索引:添加
source.remote,并填写远程集群 URL 和凭据。远程重新索引不支持切片;可通过基于查询的分区(日期范围、词项筛选)并行发起请求来弥补。确认远程主机已加入 Self-Managed / ECH 的允许列表(在集群配置中设置reindex.remote.whitelist);Serverless 在内部管理允许列表(仅限 ECH 远程集群,技术预览版)。
所需信息:源索引名称、目标索引名称,以及它们是否属于同一集群。
- 同一集群 — 使用本地重新索引:仅设置
-
检查源数据——绝不要猜测字段名称或文档数。 调用
GET /{source}/_mapping,以确认字段名称和类型。调用GET /{source}/_count(或在 Self-Managed / ECH 上调用GET /_cat/count/{source}?h=count),了解文档数量。判断标准:完整复制还是筛选子集。
- 完整复制 — 省略
source.query(默认匹配全部文档)。 - 筛选子集 — 使用 Query DSL 添加
source.query。对于时间范围,在时间戳字段上使用range筛选(通常为@timestamp),例如,2025 年 1 月可使用"gte": "2025-01-01", "lt": "2025-02-01"。如果用户要求日期范围或其他筛选条件,不要复制整个索引。
所需信息:用户的筛选条件,以及经映射确认的字段名称。
- 完整复制 — 省略
-
复制前准备目标索引。
_reindex不会复制映射、分片数或分析器。根据源映射,通过PUT /{dest}创建目标索引,并显式设置参数和映射。- 在 Self-Managed / ECH 上:复制期间在目标索引上设置
number_of_replicas: 0和refresh_interval: "-1",以提升写入吞吐量;完成后通过PUT /{dest}/_settings恢复生产环境的值。 - 在 Serverless 上:省略
number_of_shards和number_of_replicas(由 Elastic 管理);复制期间可以设置refresh_interval: "-1"。 - 对于数据流目标:确保索引模板中存在
data_stream: {},创建数据流,并将dest.op_type设置为"create"(仅追加)。 决策:创建/准备目标索引,而不是依赖自动创建和动态映射。映射错误或缺失会导致部分失败或静默的类型强制转换。
所需数据:目标名称、修正后的或兼容的映射,以及部署特定的设置限制。
- 在 Self-Managed / ECH 上:复制期间在目标索引上设置
-
构建并提交重建索引请求。 对于可能需要数秒以上的复制操作,或用户表示索引很大时,调用
POST /_reindex?wait_for_completion=false——响应会立即返回一个任务 ID,而不是阻塞等待。请求正文要点:
source.index— 源索引或数据流(名称要正确,不要与dest.index颠倒)。dest.index— 第 4 步中准备好的目标索引。source.query— 仅在第 3 步选择了筛选子集时才包含。conflicts: "proceed"— 重试未完全完成的重建索引时使用。- 可选调优项:
source.size(批次大小)、requests_per_second(限流)、仅在本地重建索引时使用slices=auto(按主分片并行处理——远程重建索引绝不可用)、scroll(在集群速度较慢时延长保留时间)、max_docs(测试运行)、script(转换)、dest.pipeline(摄取时增强)。
筛选子集示例(仅 2025 年 1 月):
{ "source": { "index": "eval-reindex-src", "query": { "range": { "@timestamp": { "gte": "2025-01-01", "lt": "2025-02-01" } } } }, "dest": { "index": "eval-reindex-jan" } }如果任务是筛选子集复制或直接迁移文档,不要使用
_split、_shrink或快照/还原——这些 API 用于解决其他问题。 -
跟踪任务直至完成。 保存重建索引响应中的任务 ID。轮询
GET /_tasks/{task_id},直到completed为true。读取status.total、status.created和response.failures。在 Self-Managed / ECH 上,还可以使用GET /_tasks?actions=*reindex&detailed列出正在运行的重建索引任务;在 Serverless 上,只能按任务 ID 查询(不支持列出/取消)。无需取消任务,即可通过POST /_reindex/{task_id}/_rethrottle?requests_per_second=N在任务运行期间调整限流。 -
验证并报告目标索引文档数。 调用
GET /{dest}/_count(适用于所有部署类型)。在 Self-Managed / ECH 上,还可以使用GET /_cat/count/{dest}?h=count。将源筛选条件的预期结果与目标索引文档数进行比较。报告目标索引的确切文档数——不要估算或猜测。全量复制成功后,使用
PUT /{dest}/_settings恢复目标索引的生产设置(在 Self-Managed / ECH 上设置副本数和刷新间隔;在 Serverless 上仅设置刷新间隔)。
部署限制
| 功能 | Self-Managed / ECH | Serverless |
|---|---|---|
| 本地重建索引 | 完全支持 | 完全支持 |
| 远程重建索引 | 完全支持 | 技术预览版 — 仅支持 ECH 远程端 |
number_of_shards/replicas | 用户可配置 | 由系统管理 — 创建索引时省略 |
slices=auto(仅本地) | 支持 | 支持本地重建索引 |
GET /_cat/count/{index} | 支持 | 不可用 — 使用 GET /{index}/_count |
GET /_tasks(列出/取消) | 完全支持 | 仅可按任务 ID 查询 |
PUT /_cluster/settings | 支持 | 禁止 |
_split / _shrink | 支持 | 不可用 |
优先考虑其他方案
- 运行时字段 — 如果无需更改已存储的值,可在不重建索引的情况下修正字段类型不匹配,或添加计算字段。
- 别名 — 透明地重定向查询;与重建索引结合使用,可在不中断服务的情况下更改映射。
- 快照和还原(Self-Managed / ECH)— 无需转换时,可更快地传输整个索引。
请参阅 references/patterns.md 中的决策树。
参考资料
- API 参数参考 — 完整的
POST /_reindex请求体和查询参数 - 多步骤模式 — 映射变更、远程迁移、合并、摄取管道、性能
- 调优 — 批次大小(
source.size)、时间戳、版本控制 - 故障排除 — 映射冲突、滚动超时、计数不匹配
示例
“将 logs-2024 复制到一个使用更正后映射的新索引中” — 先创建目标索引,然后执行重新索引:
POST /_reindex
{ "source": { "index": "logs-2024" }, "dest": { "index": "logs-2024-v2" } }
“并行重新索引大型索引并限制速率” — 自动切片并限制请求速率:
POST /_reindex?slices=auto&requests_per_second=2000
{ "source": { "index": "events" }, "dest": { "index": "events-v2" } }
“仅迁移近期文档” — 使用查询筛选源数据:
POST /_reindex
{
"source": { "index": "metrics", "query": { "range": { "@timestamp": { "gte": "now-30d" } } } },
"dest": { "index": "metrics-recent" }
}
指南
- 先确认部署类型。 调用
GET /并读取build_flavor;分片、副本、集群设置和任务 API 在 Self-Managed / ECH 与 Serverless 之间有所不同(请参阅部署限制)。 - 合适时优先考虑替代方案。 运行时字段、别名或快照与恢复通常可以避免完整重新索引。
- 为复制调整目标索引。 在 Self-Managed / ECH 上,复制期间将
number_of_replicas: 0和refresh_interval: "-1"设为临时值,完成后再恢复生产设置;在 Serverless 上,这些设置由系统管理。 - 并行执行大型复制任务。 对本地重新索引使用
slices=auto,并通过requests_per_second限流,以保护集群。 - 以异步方式运行大型任务。 使用
wait_for_completion=false提交任务,并轮询任务状态,而不是阻塞等待。 - 按数量核验。 将源筛选条件的预期结果与目标索引的精确
GET /{dest}/_count结果进行比较 — 切勿估算。
操作
| HTTP API(简写) | elastic CLI 命令 |
|---|---|
GET / | elastic es info |
GET /{index}/_mapping | elastic es indices get-mapping --index '<index>' |
GET /{index}/_count | elastic es count --index '<index>' |
GET /_cat/count/{index}?h=count | elastic es cat count --index '<index>' --h count |
PUT /{index} | elastic es indices create --index '<index>' --mappings '<json>' --settings '<json>' |
PUT /{index}/_settings | elastic es indices put-settings --index '<index>' --settings '<json>' |
POST /_reindex?wait_for_completion=false | elastic es reindex --wait-for-completion false --source '<json>' --dest '<json>' |
GET /_tasks/{task_id} | elastic es tasks get --task-id '<task_id>' |
GET /_tasks?actions=*reindex&detailed | elastic es tasks list --actions '*reindex' --detailed |
POST /_tasks/{task_id}/_cancel | elastic es tasks cancel --task-id '<task_id>' |
POST /_reindex/{task_id}/_rethrottle?requests_per_second=N | elastic es reindex-rethrottle --task-id '<task_id>' --requests-per-second <N> |