Using a script to conditionally update a document in Elasticsearch Using a script to conditionally update a document in Elasticsearch elasticsearch elasticsearch

Using a script to conditionally update a document in Elasticsearch


Elasticsearch has built-in optimistic concurrency control (+ here and here).

The way it works is that the Update API allows you two use the version parameter in order to control whether the update should proceed or not.

So taking your above example, the first index/update operation would create a document with version: 1. Then take the case where you have two concurrent requests. Both components A and B will send an updated document, they initially have both retrieved the document with version: 1 and will specify that version in their request (see version=1 in the query string below). Elasticsearch will update the document if and only if the provided version is the same as the current one

Component A and B both send this, but A's request is the first to make it:

curl -XPOST 'localhost:9200/test/type1/1/_update?version=1' -d '{  "doc": {    "name": "new_name"   },  "doc_as_upsert": true}'

At this point the version of the document will be 2 and B's request will end up with HTTP 409 Conflict, because B assumed the document was still at version 1, even though the version increased in the meantime due to A's request.

B can definitely retrieve the document with the new version (i.e. 2) and try its update again, but this time with ?version=2in the URL. If it's the first one to reach ES, the update will succeed.


I think the script should be like this:

"script": "if(ctx._source.user_update_time > my_new_time) ctx._source.user_update_time=my_new_time;"

or

"script": "ctx._source.user_update_time > my_new_time ? ctx.op=\"none\" : ctx._source.user_update_time=my_new_time"