Skip to content

Commit

Permalink
[DOCS] Reformat update API reference. (#45423)
Browse files Browse the repository at this point in the history
* [DOCS] Reformat update API reference.
  • Loading branch information
debadair committed Aug 22, 2019
1 parent d4e676b commit 6c352ff
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 73 deletions.
2 changes: 1 addition & 1 deletion docs/reference/docs/index_.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ using a PUT request. Omit to automatically generate an ID when using a
POST request.


[[docs--api-query-params]]
[[docs-index-api-query-params]]
==== {api-query-parms-title}

include::{docdir}/rest-api/common-parms.asciidoc[tag=doc-seq-no]
Expand Down
183 changes: 111 additions & 72 deletions docs/reference/docs/update.asciidoc
Original file line number Diff line number Diff line change
@@ -1,19 +1,86 @@
[[docs-update]]
=== Update API
++++
<titleabbrev>Update</titleabbrev>
++++

The update API allows to update a document based on a script provided.
The operation gets the document (collocated with the shard) from the
index, runs the script (with optional script language and parameters),
and indexes back the result (also allows to delete, or ignore the
operation). It uses versioning to make sure no updates have happened
during the "get" and "reindex".
Updates a document using the specified script.

Note, this operation still means full reindex of the document, it just
removes some network roundtrips and reduces chances of version conflicts
between the get and the index. The `_source` field needs to be enabled
for this feature to work.
[[docs-update-api-request]]
==== {api-request-title}

For example, let's index a simple doc:
`POST /<index/_update/<_id>`

[[update-api-desc]]
==== {api-description-title}

Enables you script document updates. The script can update, delete, or skip
modifying the document. The update API also supports passing a partial document,
which is merged into the existing document. To fully replace an existing
document, use the <<docs-index_,`index` API>>.

This operation:

. Gets the document (collocated with the shard) from the index.
. Runs the specified script.
. Indexes the result.

The document must still be reindexed, but using `update` removes some network
roundtrips and reduces chances of version conflicts between the GET and the
index operation.

The `_source` field must be enabled to use `update`. In addition to `_source`,
you can access the following variables through the `ctx` map: `_index`,
`_type`, `_id`, `_version`, `_routing`, and `_now` (the current timestamp).

[[docs-update-api-path-params]]
==== {api-path-parms-title}

`<index>`::
(Required, string) Name of the target index. By default, the index is created
automatically if it doesn't exist. For more information, see <<index-creation>>.

`<_id>`::
(Required, string) Unique identifier for the document to be updated.

[[docs-update-api-query-params]]
==== {api-query-parms-title}

include::{docdir}/rest-api/common-parms.asciidoc[tag=doc-seq-no]

include::{docdir}/rest-api/common-parms.asciidoc[tag=doc-primary-term]

`lang`::
(Optional, string) The script language. Default: `painless`.

include::{docdir}/rest-api/common-parms.asciidoc[tag=doc-refresh]

`retry_on_conflict`::
(Optional, integer) Specify how many times should the operation be retried when
a conflict occurs. Default: 0.

include::{docdir}/rest-api/common-parms.asciidoc[tag=doc-refresh]

include::{docdir}/rest-api/common-parms.asciidoc[tag=doc-routing]

`_source`::
(Optional, list) Set to `false` to disable source retrieval (default: `true`).
You can also specify a comma-separated list of the fields you want to retrieve.

`_source_excludes`::
(Optional, list) Specify the source fields you want to exclude.

`_source_includes`::
(Optional, list) Specify the source fields you want to retrieve.

include::{docdir}/rest-api/common-parms.asciidoc[tag=timeoutparms]

include::{docdir}/rest-api/common-parms.asciidoc[tag=doc-wait-for-active-shards]

[[update-api-example]]
==== {api-examples-title}

First, let's index a simple doc:

[source,js]
--------------------------------------------------
Expand All @@ -25,10 +92,8 @@ PUT test/_doc/1
--------------------------------------------------
// CONSOLE

[float]
==== Scripted updates

Now, we can execute a script that would increment the counter:
To increment the counter, you can submit an update request with the
following script:

[source,js]
--------------------------------------------------
Expand All @@ -46,8 +111,8 @@ POST test/_update/1
// CONSOLE
// TEST[continued]

We can add a tag to the list of tags (if the tag exists, it
still gets added, since this is a list):
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):

[source,js]
--------------------------------------------------
Expand All @@ -65,11 +130,11 @@ POST test/_update/1
// CONSOLE
// TEST[continued]

We can remove a tag from the list of tags. Note that the Painless function to
`remove` a tag takes as its parameter the array index of the element you wish
to remove, so you need a bit more logic to locate it while avoiding a runtime
error. Note that if the tag was present more than once in the list, this will
remove only one occurrence of it:
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.

[source,js]
--------------------------------------------------
Expand All @@ -87,11 +152,8 @@ POST test/_update/1
// CONSOLE
// TEST[continued]

In addition to `_source`, the following variables are available through
the `ctx` map: `_index`, `_type`, `_id`, `_version`, `_routing`,
and `_now` (the current timestamp).

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

[source,js]
--------------------------------------------------
Expand All @@ -103,7 +165,7 @@ POST test/_update/1
// CONSOLE
// TEST[continued]

Or remove a field from the document:
Conversely, this script removes the field `new_field`:

[source,js]
--------------------------------------------------
Expand All @@ -115,9 +177,9 @@ POST test/_update/1
// CONSOLE
// TEST[continued]

And, we can even change the operation that is executed. This example deletes
the doc if the `tags` field contains `green`, otherwise it does nothing
(`noop`):
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`):

[source,js]
--------------------------------------------------
Expand All @@ -136,13 +198,8 @@ POST test/_update/1
// TEST[continued]

[float]
==== Updates with a partial document
===== Update part of a document

The update API also supports passing a partial document,
which will be merged into the existing document (simple recursive merge,
inner merging of objects, replacing core "keys/values" and arrays).
To fully replace the existing document, the <<docs-index_,`index` API>> should
be used instead.
The following partial update adds a new field to the
existing document:

Expand All @@ -158,14 +215,14 @@ POST test/_update/1
// CONSOLE
// TEST[continued]

If both `doc` and `script` are specified, then `doc` is ignored. Best is
to put your field pairs of the partial document in the script itself.
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.

[float]
==== Detecting noop updates
===== Detect noop updates

If `doc` is specified its value is merged with the existing `_source`.
By default updates that don't change anything detect that they don't change anything and return `"result": "noop"` like this:
By default updates that don't change anything detect that they don't change
anything and return `"result": "noop"`:

[source,js]
--------------------------------------------------
Expand All @@ -179,9 +236,8 @@ POST test/_update/1
// CONSOLE
// TEST[continued]

If `name` was `new_name` before the request was sent then the entire update
request is ignored. The `result` element in the response returns `noop` if
the request was ignored.
If the value of `name` is already `new_name`, the update
request is ignored and the `result` element in the response returns `noop`:

[source,js]
--------------------------------------------------
Expand All @@ -200,7 +256,7 @@ the request was ignored.
--------------------------------------------------
// TESTRESPONSE

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

[source,js]
--------------------------------------------------
Expand All @@ -217,11 +273,11 @@ POST test/_update/1

[[upserts]]
[float]
==== Upserts
===== Upsert

If the document does not already exist, the contents of the `upsert` element
will be inserted as a new document. If the document does exist, then the
`script` will be executed instead:
are inserted as a new document. If the document exists, the
`script` is executed:

[source,js]
--------------------------------------------------
Expand All @@ -244,11 +300,10 @@ POST test/_update/1

[float]
[[scripted_upsert]]
===== `scripted_upsert`
===== Scripted upsert

If you would like your script to run regardless of whether the document exists
or not -- i.e. the script handles initializing the document instead of the
`upsert` element -- then set `scripted_upsert` to `true`:
To run the script whether or not the document exists, set `scripted_upsert` to
`true`:

[source,js]
--------------------------------------------------
Expand All @@ -274,10 +329,10 @@ POST sessions/_update/dh3sgudg8gsrgl

[float]
[[doc_as_upsert]]
===== `doc_as_upsert`
===== Doc as upsert

Instead of sending a partial `doc` plus an `upsert` doc, setting
`doc_as_upsert` to `true` will use the contents of `doc` as the `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:

[source,js]
Expand Down Expand Up @@ -343,19 +398,3 @@ matches the one specified.

[NOTE]
.The update API does not support versioning other than internal
=====================================================
External (version types `external` and `external_gte`) or forced (version type `force`)
versioning is not supported by the update API as it would result in Elasticsearch
version numbers being out of sync with the external system. Use the
<<docs-index_,`index` API>> instead.
=====================================================

`if_seq_no` and `if_primary_term`::

Update operations can be made conditional and only be performed if the last
modification to the document was assigned the sequence number and primary
term specified by the `if_seq_no` and `if_primary_term` parameters. If a
mismatch is detected, the operation will result in a `VersionConflictException`
and a status code of 409. See <<optimistic-concurrency-control>> for more details.

0 comments on commit 6c352ff

Please sign in to comment.