Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to do an atomic increment using elastic search update?

will this update in elastic search cause an atomic increment? Or will it be non-atomic?

curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
    "script" : "ctx._source.counter += count",
    "params" : {
        "count" : 1
    }
}'
like image 872
MonkeyBonkey Avatar asked May 29 '15 20:05

MonkeyBonkey


People also ask

Can you update an Elasticsearch index?

If the Elasticsearch security features are enabled, you must have the manage index privilege for the target data stream, index, or alias. [7.9] If the request targets an index or index alias, you can also update its mapping with the create , create_doc , index , or write index privilege.

How do I update multiple fields in Elasticsearch?

Just add a semicolon after the first statement and add a second statement ;-) { "script" : { "inline": "ctx. _source.

Is Elasticsearch Atomic?

Create, update, and delete operations in Elasticsearch are atomic at the document level, which means that creating, modifying, or deleting a single document either fully succeeds or fails.

Can you update a document in Elasticsearch?

DescriptioneditEnables you to 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 index API.


2 Answers

I would argue that the suggested update script is atomic, the referred Optimistic Concurrency Control talks about updates on documents which are not atomic (meaning that parallel update requests might get the document into an "inconsistent" unintended state).

Ah, after reading more docs about Partial Updates to Documents I learned that actually it is not atomic, but it checks the version number and fails if they don't match (so updates won't silently get lost, as is the case with non-atomic increments on CPUs):

To avoid losing data, the update API retrieves the current _version of the document in the retrieve step, and passes that to the index request during the reindex step. If another process has changed the document between retrieve and reindex, then the _version number won’t match and the update request will fail.

However there is an easy fix to make it work just the same as atomic increments:

For many uses of partial update, it doesn’t matter that a document has been changed. For instance, if two processes are both incrementing the page-view counter, it doesn’t matter in which order it happens; if a conflict occurs, the only thing we need to do is reattempt the update.

This can be done automatically by setting the retry_on_conflict parameter to the number of times that update should retry before failing; it defaults to 0.

like image 69
NikoNyrh Avatar answered Sep 21 '22 02:09

NikoNyrh


Non-atomic. You need to use the version parameter to tell ES to update the document only if it has a certain version: https://www.elastic.co/guide/en/elasticsearch/guide/master/optimistic-concurrency-control.html

For example: /test/type1/1/_update?version=5

like image 33
Andrei Stefan Avatar answered Sep 17 '22 02:09

Andrei Stefan