|  | @@ -1,18 +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).
 | 
	
		
			
				|  |  | +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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -24,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -45,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -64,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -86,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -102,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -114,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -135,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:
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -157,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -178,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -201,7 +258,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -218,11 +275,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -245,11 +302,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]
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
	
		
			
				|  | @@ -275,10 +331,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]
 | 
	
	
		
			
				|  | @@ -293,51 +349,3 @@ POST test/_update/1
 | 
	
		
			
				|  |  |  --------------------------------------------------
 | 
	
		
			
				|  |  |  // CONSOLE
 | 
	
		
			
				|  |  |  // TEST[continued]
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -[float]
 | 
	
		
			
				|  |  | -==== Parameters
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -The update operation supports the following query-string parameters:
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -[horizontal]
 | 
	
		
			
				|  |  | -`retry_on_conflict`::
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -In between the get and indexing phases of the update, it is possible that
 | 
	
		
			
				|  |  | -another process might have already updated the same document.  By default, the
 | 
	
		
			
				|  |  | -update will fail with a version conflict exception.  The `retry_on_conflict`
 | 
	
		
			
				|  |  | -parameter controls how many times to retry the update before finally throwing
 | 
	
		
			
				|  |  | -an exception.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -`routing`::
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Routing is used to route the update request to the right shard and sets the
 | 
	
		
			
				|  |  | -routing for the upsert request if the document being updated doesn't exist.
 | 
	
		
			
				|  |  | -Can't be used to update the routing of an existing document.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -`timeout`::
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Timeout waiting for a shard to become available.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -`wait_for_active_shards`::
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -The number of shard copies required to be active before proceeding with the update operation.
 | 
	
		
			
				|  |  | -See <<index-wait-for-active-shards,here>> for details.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -`refresh`::
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Control when the changes made by this request are visible to search. See
 | 
	
		
			
				|  |  | -<<docs-refresh, refresh>>.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -`_source`::
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -Allows to control if and how the updated source should be returned in the response.
 | 
	
		
			
				|  |  | -By default the updated source is not returned.
 | 
	
		
			
				|  |  | -See <<request-body-search-source-filtering, Source filtering>> for details.
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -`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.
 |