| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- [[docs-update]]
- == Update API
- 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 index 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".
- 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 need to be enabled
- for this feature to work.
- For example, lets index a simple doc:
- [source,js]
- --------------------------------------------------
- curl -XPUT localhost:9200/test/type1/1 -d '{
- "counter" : 1,
- "tags" : ["red"]
- }'
- --------------------------------------------------
- Now, we can execute a script that would increment the counter:
- [source,js]
- --------------------------------------------------
- curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
- "script" : "ctx._source.counter += count",
- "params" : {
- "count" : 4
- }
- }'
- --------------------------------------------------
- We can also add a tag to the list of tags (note, if the tag exists, it
- will still add it, since its a list):
- [source,js]
- --------------------------------------------------
- curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
- "script" : "ctx._source.tags += tag",
- "params" : {
- "tag" : "blue"
- }
- }'
- --------------------------------------------------
- We can also add a new field to the document:
- [source,js]
- --------------------------------------------------
- curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
- "script" : "ctx._source.text = \"some text\""
- }'
- --------------------------------------------------
- We can also remove a field from the document:
- [source,js]
- --------------------------------------------------
- curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
- "script" : "ctx._source.remove(\"text\")"
- }'
- --------------------------------------------------
- And, we can delete the doc if the tags contain blue, or ignore (noop):
- [source,js]
- --------------------------------------------------
- curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
- "script" : "ctx._source.tags.contains(tag) ? ctx.op = \"delete\" : ctx.op = \"none\"",
- "params" : {
- "tag" : "blue"
- }
- }'
- --------------------------------------------------
- *Note*: Be aware of MVEL and handling of ternary operators and
- assignments. Assignment operations have lower precedence than the
- ternary operator. Compare the following statements:
- [source,js]
- --------------------------------------------------
- // Will NOT update the tags array
- ctx._source.tags.contains(tag) ? ctx.op = \"none\" : ctx._source.tags += tag
- // Will update
- ctx._source.tags.contains(tag) ? (ctx.op = \"none\") : ctx._source.tags += tag
- // Also works
- if (ctx._source.tags.contains(tag)) { ctx.op = \"none\" } else { ctx._source.tags += tag }
- --------------------------------------------------
- The update API also support 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). For
- example:
- [source,js]
- --------------------------------------------------
- curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
- "doc" : {
- "name" : "new_name"
- }
- }'
- --------------------------------------------------
- If both `doc` and `script` is specified, then `doc` is ignored. Best is
- to put your field pairs of the partial document in the script itself.
- By default if `doc` is specified then the document is always updated even
- if the merging process doesn't cause any changes. Specifying `detect_noop`
- as `true` will cause Elasticsearch to check if there are changes and, if
- there aren't, turn the update request into a noop. For example:
- [source,js]
- --------------------------------------------------
- curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
- "doc" : {
- "name" : "new_name"
- },
- "detect_noop": true
- }'
- --------------------------------------------------
- If `name` was `new_name` before the request was sent then the entire update
- request is ignored.
- === Upserts
- There is also support for `upsert`. If the document does
- not already exists, the content of the `upsert` element will be used to
- index the fresh doc:
- [source,js]
- --------------------------------------------------
- curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
- "script" : "ctx._source.counter += count",
- "params" : {
- "count" : 4
- },
- "upsert" : {
- "counter" : 1
- }
- }'
- --------------------------------------------------
- coming[1.4.0]
- If the document does not exist you may want your update script to
- run anyway in order to initialize the document contents using
- business logic unknown to the client. In this case pass the
- new `scripted_upsert` parameter with the value `true`.
- [source,js]
- --------------------------------------------------
- curl -XPOST 'localhost:9200/sessions/session/dh3sgudg8gsrgl/_update' -d '{
- "script_id" : "my_web_session_summariser",
- "scripted_upsert":true,
- "params" : {
- "pageViewEvent" : {
- "url":"foo.com/bar",
- "response":404,
- "time":"2014-01-01 12:32"
- }
- },
- "upsert" : {
- }
- }'
- --------------------------------------------------
- The default `scripted_upsert` setting is `false` meaning the script is not executed for inserts.
- However, in scenarios like the one above we may be using a non-trivial script stored
- using the new "indexed scripts" feature. The script may be deriving properties
- like the duration of our web session based on observing multiple page view events so the
- client can supply a blank "upsert" document and allow the script to fill in most of the details
- using the events passed in the `params` element.
- Last, the upsert facility also supports `doc_as_upsert`. So that the
- provided document will be inserted if the document does not already
- exist. This will reduce the amount of data that needs to be sent to
- elasticsearch.
- [source,js]
- --------------------------------------------------
- curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
- "doc" : {
- "name" : "new_name"
- },
- "doc_as_upsert" : true
- }'
- --------------------------------------------------
- === Parameters
- The update operation supports similar parameters as the index API,
- including:
- [horizontal]
- `routing`:: Sets the routing that will be used to route the
- document to the relevant shard.
- `parent`:: Simply sets the routing.
- `timeout`:: Timeout waiting for a shard to become available.
- `replication`:: The replication type for the delete/index operation
- (sync or async).
- `consistency`:: The write consistency of the index/delete operation.
- `refresh`:: Refresh the relevant primary and replica shards (not the whole
- index) immediately after the operation occurs, so that the
- updated document appears in search results immediately.
- `fields`:: return the relevant fields from the updated document.
- Support `_source` to return the full updated
- source.
- `version` & `version_type`:: the Update API uses the Elasticsearch's versioning
- support internally to make sure the document doesn't change
- during the update. You can use the `version` parameter to specify that the
- document should only be updated if it's version matches the one specified.
- By setting version type to `force` you can force the new version of the document
- after update (use with care! with `force` there is no guarantee the document
- didn't change).Version types `external` & `external_gte` are not supported.
-
- And also support `retry_on_conflict` which controls how many times to
- retry if there is a version conflict between getting the document and
- indexing / deleting it. Defaults to `0`.
- It also allows to update the `ttl` of a document using `ctx._ttl` and
- timestamp using `ctx._timestamp`. Note that if the timestamp is not
- updated and not extracted from the `_source` it will be set to the
- update date.
|