2

I'm using ElasticSearch Update action with Upserts to create or update an existing document in the current Index, when doing in the bulk api like this

{
                    index: myIndex,
                    type: '_doc',
                    body: [
                    { index:  {_id: docItemID1 } },
                    docItem1,
                    { index:  {_id: docItemID2 } },
                    docItem2
]
                }

This works ok. Now I would like to update / append a new value to a tag field in the document item using the scripted_upsert flag and the script update action so something like:

{
   "scripted_upsert":true,
    "script" : {
        "source": "if ( !ctx._source.tags.contains(params.tag) ) ctx._source.tag.concat( params.tag)",
        "lang": "painless",
        "params" : {
            "tag" : "blue"
        }
    },
    "upsert" : {
        "tag" : ["red","green"]
    }
}

Now, I want to use the scripted_upsert to take the best of the two worlds, so I imagine something like this - if it is correct (that is my question)

    {
        "script" : {
            "source": "if ( !ctx._source.tags.contains(params.tag) ) ctx._source.tag.concat( params.tag)",
            "lang": "painless",
            "params" : {
                "tag" : myNewTag
            }
        },
        "upsert" : docItem
    }

where docItem will contain a tag item to be updated. This tag items is a comma separated list of tags like red,green.

Is this approach correct? If so which is the right body for the bulk api i.e. when using the body as [] of actions having an update script with plus scripted_upsert flag for one or more items?

1 Answer 1

3

That's correct, the docs say:

If you would like your script to run regardless of whether the document exists or not - [...] - then set scripted_upsert to true

So having both "upsert" and "script" sections is the way to go, but you have to keep the "scripted_upsert":true (which is missing from the last snippet).

Using the elasticsearch-js lib, it goes like this:

await client.bulk({
  index: 'myIndex',
  type: 'myType',
  body [
    { update: { _id: docId } },
    { script: { source, params }, scripted_upsert: true, upsert: docItem },
  ],
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.