elasticsearch-reindex について
elastic CLIでElasticsearchのreindex機能を使い、インデックスやデータストリームの文書をコピーするスキルです。移行や条件付きコピー向けに、コピー先マッピングの事前準備、非同期タスクの追跡、コピー先件数の検証を行います。
主な機能
- 01インデックスやデータストリームから文書をコピー
- 02クエリでコピー元の文書を絞り込み
- 03コピー前にコピー先マッピングを準備
- 04非同期reindexタスクの実行と追跡
- 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)で操作を記載しています。このドキュメントの最後にある操作の表では、各省略形式に対応する elastic CLI コマンドを示しています。HTTP API を直接呼び出すのではなく、必ず CLI を使用してください。
手順
-
接続性とデプロイメントの種類を確認します。
GET /を呼び出します。build_flavorとversion.numberを確認して、シャード、レプリカ、クラスター設定の API が利用可能かどうかを判断します(Serverless ではシャードとレプリカが内部的に管理され、ほとんどの_cluster/*API がブロックされます)。判断基準:クラスターに接続できる場合にのみ続行します。呼び出しに失敗した場合は停止し、エンドポイントや認証情報を推測しないでください。 -
ローカル再インデックスとリモート再インデックスのどちらを使うか決めます。 ソースとコピー先がどこにあるかを比較します。
- 同じクラスター — ローカル再インデックスを使用し、
source.indexとdest.indexのみを指定します。両方のインデックスが接続先のクラスターにある場合、source.remoteは追加しないでください。 - 異なるクラスター — リモートからの再インデックスを使用し、リモートクラスターの URL と認証情報を指定して
source.remoteを追加します。リモート再インデックスではスライスがサポートされません。並列リクエストでクエリベースのパーティション分割(日付範囲、用語フィルター)を使って補ってください。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を追加します。時間範囲を指定する場合は、タイムスタンプフィールド(通常は@timestamp)にrangeフィルターを使用します。たとえば、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 では、Elastic が管理する
number_of_shardsとnumber_of_replicasを省略します。コピー中にrefresh_interval: "-1"を設定してもかまいません。 - データストリームをコピー先にする場合は、
data_stream: {}を含むインデックステンプレートが存在することを確認し、データストリームを作成して、dest.op_typeを"create"(追記のみ)に設定します。 判断:動的マッピングによる自動作成に頼るのではなく、ターゲットを作成/準備します。マッピングが誤っている、または欠落していると、部分的な失敗や暗黙的な型変換が発生します。
必要なデータ:宛先名、修正済みまたは互換性のあるマッピング、およびデプロイメント固有の設定制約。
- Self-Managed / ECH では、書き込みスループットを高めるため、コピー中はコピー先の
-
reindex リクエストを構築して送信します。 数秒以上かかる可能性があるコピー、またはユーザーがインデックスが大きいと述べた場合は、
POST /_reindex?wait_for_completion=falseを呼び出します。レスポンスはブロックする代わりに、すぐにタスク IDを返します。リクエストボディの必須項目:
source.index— ソースインデックスまたはデータストリーム(dest.indexと逆にしないよう、正しい名前を使用)。dest.index— 手順 4 で準備した宛先。source.query— 手順 3 でフィルタリングされたサブセットを選択した場合にのみ含めます。conflicts: "proceed"— 部分的に完了した reindex を再試行する場合。- オプションのチューニング:
source.size(バッチサイズ)、requests_per_second(スロットル)、ローカル reindex のみでslices=auto(プライマリシャードごとに並列化 — リモートでは決して使用しない)、scroll(低速なクラスターで keep-alive を増やす)、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 は異なる問題を解決します。 -
タスクを完了まで追跡します。 reindex レスポンスからタスク ID を保存します。
completedがtrueになるまでGET /_tasks/{task_id}をポーリングします。status.total、status.created、response.failuresを読み取ります。Self-Managed / ECH では、GET /_tasks?actions=*reindex&detailedでアクティブな reindex タスクを一覧表示することもできます。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 |
|---|---|---|
| ローカル reindex | 完全サポート | 完全サポート |
| リモートからの reindex | 完全サポート | テクニカルプレビュー — ECH リモートのみ |
number_of_shards/replicas | ユーザー設定可能 | マネージド — インデックス作成時に省略 |
slices=auto(ローカルのみ) | サポート | ローカル reindex でサポート |
GET /_cat/count/{index} | サポート | 利用不可 — GET /{index}/_count を使用 |
GET /_tasks(一覧/キャンセル) | 完全 | タスク ID による取得のみ |
PUT /_cluster/settings | サポート | ブロック |
_split / _shrink | サポート | 利用不可 |
まず代替手段を検討する
- ランタイムフィールド — 保存された値を変更する必要がない場合、reindex せずにフィールド型の不一致を修正したり、計算フィールドを追加したりできます。
- エイリアス — クエリを透過的にリダイレクトします。ゼロダウンタイムのマッピング変更のために reindex と組み合わせて使用します。
- スナップショットとリストア(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> |