Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk10 min

How to Run CRUD Operations in Elasticsearch: A Safe REST API Guide

A practical Elasticsearch CRUD guide covering create-only and replacement writes, partial and scripted updates, reads, deletes, bulk NDJSON, refresh behavior and protection against stale overwrites.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Elasticsearch CRUD means creating, reading, updating and deleting JSON documents through its REST APIs. Use PUT with a known ID when your application owns identity, POST when Elasticsearch should generate an ID, GET to retrieve a document, _update for partial or scripted changes, and DELETE for removal. For high-volume independent changes, send newline-delimited JSON (NDJSON) to _bulk. Choose create-only, replacement, partial-update and concurrency semantics deliberately: an unconditional write can otherwise overwrite a newer document.

What CRUD means in Elasticsearch

Elasticsearch stores application records as JSON documents inside indices. A document has a source object (the fields you send), an index name and, optionally, an application-chosen document ID. Elasticsearch also tracks internal metadata such as sequence numbers and primary terms so writes can be ordered safely.

As an Amazon Associate I earn from qualifying purchases.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The document APIs cover single-document index, get, delete and update operations, plus bulk, multi-get, update-by-query and delete-by-query operations. CRUD is therefore more than four HTTP verbs: the correct API depends on whether you know the ID, whether the write is a replacement or a patch, and whether many independent operations can be batched.

Prepare an index before writing documents

  • Choose a stable ID strategy. Use an application key when records must be addressable or updated later. Let Elasticsearch generate IDs only when the application does not already have a suitable identity.
  • Define mappings intentionally. Create the index and mappings before loading production data when field types, analyzers or date handling matter. Dynamic mapping can infer types, but an early mistaken value can create an inconvenient mapping.
  • Use the correct content type. Ordinary document requests use application/json. Bulk requests use application/x-ndjson.
  • Check permissions and index names. Security rules can distinguish creating, indexing, updating and deleting. If automatic index creation is disabled, create the index first.

The examples below assume an index named products and a document such as a keyboard with a numeric price.

Create a document with the Index API

Use a known ID with PUT

When the application owns identity, address the document directly with PUT /products/_doc/42:

PUT /products/_doc/42
Content-Type: application/json

{"name":"Keyboard","price":99.0}

This is an index operation, not a create-only operation. If ID 42 does not exist, Elasticsearch creates it. If it already exists, Elasticsearch replaces the stored source with the JSON you send and increments the document version. Send the complete representation when replacement is intended; omitted fields are not preserved as they would be in a patch.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Let Elasticsearch generate the ID with POST

POST /products/_doc
Content-Type: application/json

{"name":"Keyboard","price":99.0}

The POST form asks Elasticsearch to generate a document ID and returns that ID in the response. Save it if later reads, updates or deletes need to address this document.

Make creation fail when an ID already exists

Use create-only semantics when replacement would be dangerous, such as inserting an event that must never be silently overwritten. Add op_type=create to an index request:

PUT /products/_doc/42?op_type=create
Content-Type: application/json

{"name":"Keyboard","price":99.0}

If document 42 already exists, the request returns a conflict rather than replacing it. The same rule is available in bulk through the create action. Handle the conflict as an application decision: ignore it for an idempotent import, report a duplicate, or fetch and reconcile the existing document.

Read documents by ID

Get one document

GET /products/_doc/42

The response states whether the document was found and, when source storage is available, returns the JSON under _source. Treat a not-found response as a normal branch in application code rather than assuming every ID exists. A get-by-ID request is different from a search: it addresses one known document and does not require a query.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Get several known IDs

When you already have a list of IDs, use the multi-get API instead of issuing one network request per document. Multi-get is listed with the document APIs and returns per-document results, so code should inspect each item for found and missing states. It is useful for assembling a set of related records without writing a broad search query.

Understand read-after-write visibility

A successful index or update is durably processed before it is necessarily visible to search. Search visibility follows Elasticsearch refresh behavior. Request an explicit refresh only when the next search must see the write immediately; otherwise allow the normal refresh schedule, which avoids adding refresh overhead to every write. A direct get by ID can have different visibility characteristics from a search, so do not use a successful search as the only confirmation that a write was accepted.

Update a document without replacing its source

Patch selected fields with doc

The Update API applies a partial document. This example changes only the price:

POST /products/_update/42
Content-Type: application/json

{"doc":{"price":89.0}}

Fields not included in doc remain in the document. This is the appropriate choice when a client owns only a subset of fields or when sending the complete source would risk erasing fields written by another component.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Apply an atomic transformation with a Painless script

Use a script when the new value depends on the current value. The following decrements stock by the parameter n:

POST /products/_update/42
Content-Type: application/json

{"script":{"source":"ctx._source.stock -= params.n","params":{"n":1}}}

Parameters keep values separate from the script source and make the operation easier to reuse. Validate that the field exists and that the parameter is within an acceptable range; a script can otherwise create a negative or otherwise invalid business value.

Use upsert when the document may not exist

Update requests can include an upsert object for the insert-if-missing case. Bulk updates support upsert and doc_as_upsert as well. With doc_as_upsert, the partial doc also becomes the initial document when the ID is absent. Decide whether that fallback is valid for your data model before enabling it.

Distinguish update from index replacement

Operation Payload meaning Existing document Typical use
Index (PUT or POST) Complete replacement source Replaced and version incremented Authoritative full representation
Update with doc Partial field merge Unsent fields retained Change one or more known fields
Update with script Server-side transformation Script changes current source Counters, arithmetic and conditional logic
Create-only New complete source Conflict if ID exists Duplicate-proof insertion

Indexing creates a new version even when the source is unchanged. If avoiding no-op writes matters, use the Update API’s detect_noop behavior rather than repeatedly sending full replacements.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Delete documents

Delete one known ID

DELETE /products/_doc/42

Handle both successful deletion and a not-found result. A delete removes the document from the index; it does not provide a recycle bin for application recovery.

Delete by a query

For criteria-based removal, use the Delete by query API. For example, a query could target discontinued products, but the exact query is deliberately omitted here because the filter must match your retention rule:

POST /products/_delete_by_query
Content-Type: application/json

{"query":{"term":{"status":"discontinued"}}}

Review the query against a small search sample before executing it. A broad or incorrectly mapped query can remove many more documents than intended. Record the task response and failures, and use a narrower index or filter when possible.

Run many CRUD operations with the Bulk API

Bulk reduces network overhead by sending independent actions in one NDJSON request. Each action has a metadata line; index, create and update actions are followed by a source or update line, while delete has no following line.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
POST /_bulk
Content-Type: application/x-ndjson

{"index":{"_index":"products","_id":"1"}}
{"name":"Mouse","price":25}
{"update":{"_index":"products","_id":"1"}}
{"doc":{"price":20}}
{"delete":{"_index":"products","_id":"2"}}

When using curl, send the file with --data-binary so newline boundaries are preserved:

curl -X POST "http://localhost:9200/_bulk" 
  -H "Content-Type: application/x-ndjson" 
  --data-binary @operations.ndjson

The response contains a result for every item. A successful HTTP response does not mean every action succeeded: inspect each item’s status and error object, retry only the failed operations that are safe to retry, and log the original action with its ID.

Bulk action choices

Bulk action Following line Semantics
index Complete source Create or replace the ID
create Complete source Create; fail if the ID already exists
update Update body Partial doc, script, upsert or related update options
delete None Remove the ID

Bulk is a transport optimization, not a transaction. One item can fail while neighboring items succeed, and there is no automatic rollback of the whole request. Keep batches bounded for your cluster and implement item-level error handling.

Prevent stale writes with optimistic concurrency

A read-modify-write sequence is vulnerable to lost updates. Suppose client A reads price 99, client B changes it to 89, and client A then writes its older full document. Without a condition, A can overwrite B’s newer change.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Elasticsearch assigns every document operation a sequence number and a primary term on the coordinating primary shard. A read response includes the values needed to condition the next write. Send them as if_seq_no and if_primary_term:

PUT /products/_doc/42?if_seq_no=7&if_primary_term=3
Content-Type: application/json

{"name":"Keyboard","price":89.0}

If another operation changed the document after the read, the values no longer match and Elasticsearch returns HTTP 409. The stale write is rejected instead of silently replacing the newer version. The application can then re-read, merge the intended change, and try again, or surface a conflict to the user.

Concurrency options in bulk

Bulk index and delete metadata can carry the same sequence-number and primary-term conditions. Bulk update also supports retry_on_conflict for a bounded number of automatic retries. Retries are suitable for transient contention when the update operation is safe to repeat; they are not a substitute for deciding how conflicting business changes should be merged.

Situation Safer choice Reason
Insert must never replace an existing ID op_type=create or bulk create Duplicate IDs produce a conflict
Client owns the entire record Index with full source Replacement is explicit
Client owns only selected fields Update with doc Other fields remain intact
Value depends on current state Scripted update Transformation runs at Elasticsearch
Read-modify-write can race if_seq_no and if_primary_term Stale writes fail with 409
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Refresh and search consistency

CRUD success and search visibility are separate concerns. Normal refresh scheduling gives better write efficiency, while an explicit refresh gives a stronger read-after-write guarantee for a workflow that immediately searches. Use explicit refresh sparingly—for example, at the end of a user-visible import or test step—rather than attaching it to every individual write. If your next operation is a direct get by ID, determine whether search visibility is actually required before paying the refresh cost.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Data streams require a different update target

The normal indexing API cannot update an existing document by addressing a data stream as though it were an ordinary index. To update or delete a data-stream document, target the stream’s backing index. Identify the backing index from the data-stream metadata, then apply the appropriate document API there. New events should continue to follow the data stream’s append-oriented ingestion model; do not treat a stream like an unrestricted mutable table.

Permissions and automatic index creation

With security enabled, privileges are action-specific:

  • Indexing may require create, index or write.
  • Create-only requests can require create_doc.
  • Deletion requires delete or write.
  • Updates require index or write.
  • Automatic index creation depends on auto_configure, create_index or manage, according to the configured security policy.

Grant the narrowest privileges that support the workflow. A service that only reads products should not receive update or delete access. If a request fails with an authorization error, check both the target index and, for data streams, the backing index that actually stores the document.

A safe CRUD workflow

  1. Define the data model. Create mappings, choose analyzers and settle on stable IDs before loading documents.
  2. Choose write semantics per endpoint. Decide whether each operation is create-only, full replacement, partial update or scripted transformation.
  3. Implement single-document paths first. Verify the request body, response status, returned ID and not-found behavior.
  4. Add concurrency conditions to read-modify-write. Persist the last read’s sequence number and primary term and handle HTTP 409 by re-reading or reporting a conflict.
  5. Batch independent work. Build valid NDJSON, use --data-binary with curl, and inspect every bulk item result.
  6. Test destructive queries. Run the query as a search against a small sample, confirm the count and IDs, then execute Delete by query.
  7. Choose refresh behavior. Require an explicit refresh only where immediate search visibility is part of the workflow.
  8. Verify stream and permission details. For data streams, address backing indices for mutations; for secured clusters, grant only the required privileges.

Common failure modes and fixes

Symptom Likely cause Fix
Existing document unexpectedly loses fields Index API was used as though it were a partial update Send the complete source, or use _update with doc
Duplicate insert replaces earlier data Unconditional index request Use op_type=create or bulk create
HTTP 409 on a conditional write Sequence number or primary term is stale Re-read, merge and retry deliberately
Bulk request reports success but data is missing One or more item actions failed Inspect the per-item result array and retry only safe failures
Bulk parsing errors Invalid NDJSON or missing final newline Keep one JSON object per line, pair action/source lines correctly and send with --data-binary
Document is not found by search immediately after indexing Refresh has not occurred Wait for normal refresh or request an explicit refresh when required
Update or delete against a data stream is rejected Mutation targeted the stream rather than its backing index Resolve the backing index and target that index
403 authorization response Missing action or index privilege Grant the minimum required privilege and check automatic-index-creation settings

Choosing the right CRUD approach

Use a single-document request when the caller needs an immediate, individually observable result or when operations are dependent. Use Bulk for independent operations where reducing HTTP overhead matters, but design for partial failure. Use full indexing when the caller has an authoritative complete representation; use Update for patches and scripts; use create-only when an existing ID must be treated as a duplicate. Finally, add optimistic concurrency whenever a client reads a document and later writes a decision based on that older state.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.