Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
264 changes: 264 additions & 0 deletions docs/reference/elasticsearch/rest-apis/update-document.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
---
mapped_pages:
- https://www.elastic.co/guide/en/elasticsearch/reference/8.18/docs-update.html
applies_to:
stack: all
navigation_title: Update a document
---

# Update a document [update-document]

The [Update API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-update) enables you to script document updates, allowing you to update, delete, or skip modifying a document.

The following examples show common use cases, such as incrementing a counter and adding or removing elements from a list, as well as how to:

- [Update part of a document](#update-part-document)
- [Detect noop updates](#detect-noop-updates)
- [Insert or update documents with upsert](#upsert)
- [Simplify upsert with doc_as_upsert](#doc-as-upsert)

First, let's index a simple doc:

```console
PUT test/_doc/1
{
"counter" : 1,
"tags" : ["red"]
}
```
% TESTSETUP

To increment the counter, you can submit an update request with the
following script:

```console
POST test/_update/1
{
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
}
}
```

Similarly, you could use and update script to add a tag to the list of tags
(this is just a list, so the tag is added even it exists):

```console
POST test/_update/1
{
"script": {
"source": "ctx._source.tags.add(params.tag)",
"lang": "painless",
"params": {
"tag": "blue"
}
}
}
```

You could also remove a tag from the list of tags. The Painless
function to `remove` a tag takes the array index of the element
you want to remove. To avoid a possible runtime error, you first need to
make sure the tag exists. If the list contains duplicates of the tag, this
script just removes one occurrence.

```console
POST test/_update/1
{
"script": {
"source": "if (ctx._source.tags.contains(params.tag)) { ctx._source.tags.remove(ctx._source.tags.indexOf(params.tag)) }",
"lang": "painless",
"params": {
"tag": "blue"
}
}
}
```

You can also add and remove fields from a document. For example, this script
adds the field `new_field`:

```console
POST test/_update/1
{
"script" : "ctx._source.new_field = 'value_of_new_field'"
}
```

Conversely, this script removes the field `new_field`:

```console
POST test/_update/1
{
"script" : "ctx._source.remove('new_field')"
}
```
% TEST[continued]

The following script removes a subfield from an object field:

```console
PUT test/_doc/1?refresh
{
"my-object": {
"my-subfield": true
}
}
```

```console
POST test/_update/1
{
"script": "ctx._source['my-object'].remove('my-subfield')"
}
```
% TEST[continued]

Instead of updating the document, you can also change the operation that is
executed from within the script. For example, this request deletes the doc if
the `tags` field contains `green`, otherwise it does nothing (`noop`):

```console
POST test/_update/1
{
"script": {
"source": "if (ctx._source.tags.contains(params.tag)) { ctx.op = 'delete' } else { ctx.op = 'noop' }",
"lang": "painless",
"params": {
"tag": "green"
}
}
}
```

## Update part of a document [update-part-document]

The following partial update adds a new field to the
existing document:

```console
POST test/_update/1
{
"doc": {
"name": "new_name"
}
}
```

If both `doc` and `script` are specified, then `doc` is ignored. If you
specify a scripted update, include the fields you want to update in the script.


## Detect noop updates [detect-noop-updates]

By default updates that don't change anything detect that they don't change
anything and return `"result": "noop"`:

```console
POST test/_update/1
{
"doc": {
"name": "new_name"
}
}
```
% TEST[continued]

If the value of `name` is already `new_name`, the update
request is ignored and the `result` element in the response returns `noop`:

```console

{
"_shards": {
"total": 0,
"successful": 0,
"failed": 0
},
"_index": "test",
"_id": "1",
"_version": 2,
"_primary_term": 1,
"_seq_no": 1,
"result": "noop"
}
```

You can disable this behavior by setting `"detect_noop": false`:

```console
POST test/_update/1
{
"doc": {
"name": "new_name"
},
"detect_noop": false
}
```

## Insert or update documents with upsert [upsert]

An upsert operation lets you update an existing document or insert a new one if it doesn't exist, in a single request.

In this example, if the product with ID `1` exists, its price will be updated to `100`. If the product does not exist, a new document with ID `1` and a price of `50` will be inserted.

```console
POST /test/_update/1
{
"doc": {
"product_price": 100
},
"upsert": {
"product_price": 50
}
}
```

## Run a scripted upsert [scripted-upsert]

To run the script whether or not the document exists, set `scripted_upsert` to
`true`:

```console
POST test/_update/1
{
"scripted_upsert": true,
"script": {
"source": """
if ( ctx.op == 'create' ) {
ctx._source.counter = params.count
} else {
ctx._source.counter += params.count
}
""",
"params": {
"count": 4
}
},
"upsert": {}
}
```

## Simplify upsert with doc_as_upsert [doc-as-upsert]

Instead of sending a partial `doc` plus an `upsert` doc, you can set
`doc_as_upsert` to `true` to use the contents of `doc` as the `upsert`
value:

```console
POST test/_update/1
{
"doc": {
"name": "new_name"
},
"doc_as_upsert": true
}
```

::::{note}
Using [ingest pipelines](https://www.elastic.co/guide/en/elasticsearch/reference/8.18/ingest.html) with `doc_as_upsert` is not supported.
::::
1 change: 1 addition & 0 deletions docs/reference/elasticsearch/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ toc:
- file: rest-apis/searching-with-query-rules.md
- file: rest-apis/shard-request-cache.md
- file: rest-apis/term-vectors-examples.md
- file: rest-apis/update-document.md
- file: rest-apis/update-cc-api-key-examples.md
- file: rest-apis/vector-tile-search.md
- file: mapping-reference/index.md
Expand Down
Loading