Copy documents from source indices or data streams to a destination using
. An expert reindex workflow
prepares the destination explicitly, chooses local versus remote execution, filters at the source when only a subset is
needed, runs long copies asynchronously, tracks the task to completion, and verifies the destination document count
before reporting results.
This skill executes Elasticsearch operations through the
CLI. If the
CLI is not installed, tell the user what it is needed for. Do
not guess credentials, call the HTTP API directly, or attempt other workarounds.
This skill references operations in HTTP-shorthand form (e.g.,
,
,
,
GET /{index}/_settings/index.mode
,
). The
Operations table at the end of this document
maps each shorthand to the equivalent
CLI command — always use the CLI rather than calling the HTTP API
directly.
-
Confirm connectivity and deployment type. Call
. Read
and
to know whether
shard, replica, and cluster-settings APIs are available (Serverless manages shards/replicas internally and blocks
most
APIs). The decision: continue only when the cluster is reachable. If the call fails, stop — do not
guess endpoints or credentials.
-
Decide local versus remote reindex. Compare where the source and destination live.
- Same cluster — use local reindex: and only. Do not add when
both indices are on the cluster you are connected to.
- Different cluster — use reindex from remote: add with the remote cluster URL and credentials.
Remote reindex does not support slicing; compensate with query-based partitioning (date ranges, term filters)
across parallel requests. Confirm the remote host is allowlisted on Self-Managed / ECH (
in cluster config); Serverless manages allowlisting internally (ECH remotes only, Tech Preview).
Data needed: source index name(s), destination index name, and whether they share a cluster.
-
Inspect the source — never guess field names or counts. Call
to ground field names and
types. Call
(or
GET /_cat/count/{source}?h=count
on Self-Managed / ECH) to learn how many
documents exist.
The decision: full copy versus filtered subset.
- Full copy — omit (match-all behavior).
- Filtered subset — add with Query DSL. For time ranges, use a filter on the timestamp field
(commonly ), e.g.
"gte": "2025-01-01", "lt": "2025-02-01"
for January 2025. Do not run a
full-index copy when the user asked for a date range or other filter.
Data needed: the user's filter criteria and the mapping-confirmed field names.
-
Prepare the destination index before copying. does
not copy mappings, shard counts, or analyzers.
Create the destination with explicit settings and mappings derived from the source mapping via
.
- On Self-Managed / ECH: set and on the destination during the copy
for write throughput; restore production values afterward with .
- On Serverless: omit and (managed by Elastic); you may set
during the copy.
- For data stream destinations: ensure an index template with exists, create the data stream,
and set to (append-only).
The decision: create/prepare the target rather than relying on auto-creation with dynamic mapping. Wrong or missing
mappings cause partial failures or silent type coercion.
Data needed: destination name, corrected or compatible mappings, and deployment-specific settings constraints.
-
Build and submit the reindex request. Call
POST /_reindex?wait_for_completion=false
for any copy that may take
more than a few seconds or when the user says the index is large — the response returns a
task id immediately
instead of blocking.
Request body essentials:
- — source index or data stream (correct name, not reversed with ).
- — prepared destination from step 4.
- — include only when step 3 chose a filtered subset.
- — when retrying a partially complete reindex.
- Optional tuning: (batch size), (throttle), on local reindex only
(parallelize per primary shard — never for remote), (increase keep-alive on slow clusters),
(test runs), (transform), (ingest enrichment).
Example filtered subset (January 2025 only):
json
{
"source": {
"index": "eval-reindex-src",
"query": {
"range": {
"@timestamp": { "gte": "2025-01-01", "lt": "2025-02-01" }
}
}
},
"dest": { "index": "eval-reindex-jan" }
}
Do
not reach for
,
, or snapshot/restore when the task is a filtered subset copy or a straight
document migration — those APIs solve different problems.
-
Track the task to completion. Store the task id from the reindex response. Poll
until
is
. Read
,
, and
. On Self-Managed / ECH you may
also list active reindex tasks with
GET /_tasks?actions=*reindex&detailed
; on Serverless, query by task id only
(list/cancel are not available). Adjust throttling mid-flight with
POST /_reindex/{task_id}/_rethrottle?requests_per_second=N
without canceling.
-
Verify and report the destination count. Call
(works on all deployment types). On
Self-Managed / ECH you may also use
GET /_cat/count/{dest}?h=count
. Compare source filter expectations to the
destination count. Report the
exact count from the destination — do not estimate or guess.
After a successful full copy, restore production settings on the destination with
(replicas
and refresh interval on Self-Managed / ECH; refresh interval only on Serverless).
"Copy into a new index with a corrected mapping" — create the destination first, then reindex: