# Update plus With Script in Bulk

**URL:** <https://discuss.elastic.co/t/update-plus-with-script-in-bulk/157376>\
**Category:** Elasticsearch\
**Created:** [November 19, 2018, 2:10pm UTC](https://discuss.elastic.co/t/update-plus-with-script-in-bulk/157376 "2018-11-19T14:10:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Loreto\_Parisi](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/loreto_parisi/32/37830_2.png) [@Loreto\_Parisi](https://discuss.elastic.co/u/Loreto_Parisi)\
**Post date:** [November 19, 2018, 2:10pm UTC](https://discuss.elastic.co/t/update-plus-with-script-in-bulk/157376/1 "2018-11-19T14:10:16Z")

</div>

I'm using the bulk api for update actions with `doc_as_upsert` flag, in order to insert or update a document. This works ok. Now I would like to run a script as well for new or updated documents. Shall I use the `script` tag plus `scripted_upsert` or only the `script` tag?

---

<div class="post-metadata">

**Author:** ![rjernst](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rjernst/32/6363_2.png) [@rjernst](https://discuss.elastic.co/u/rjernst)\
**Post date:** [November 19, 2018, 11:38pm UTC](https://discuss.elastic.co/t/update-plus-with-script-in-bulk/157376/2 "2018-11-19T23:38:10Z")

</div>

I believe that is correct, [according to the docs](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html#_literal_scripted_upsert_literal).

---

<div class="post-metadata">

**Author:** ![Loreto\_Parisi](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/loreto_parisi/32/37830_2.png) [@Loreto\_Parisi](https://discuss.elastic.co/u/Loreto_Parisi)\
**Post date:** [November 20, 2018, 12:03pm UTC](https://discuss.elastic.co/t/update-plus-with-script-in-bulk/157376/3 "2018-11-20T12:03:45Z")

</div>

Thank you. Another question about this. Is then possibile to combine both?  
I mean, how I'm using the `update` plus `doc_as_upsert` like . to update two documents in bulk I will do

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

```

With the `script` action I would like to update / append a new value to a `tag` field in the document item 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" : myNewTag
        }
    },
    "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 when doing the first approach with the `bulk` api, i.e. when using the `body` as `[]` of actions having an update with the `scripted_upsert` flag?

---

<div class="post-metadata">

**Author:** ![rjernst](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rjernst/32/6363_2.png) [@rjernst](https://discuss.elastic.co/u/rjernst)\
**Post date:** [November 20, 2018, 5:23pm UTC](https://discuss.elastic.co/t/update-plus-with-script-in-bulk/157376/4 "2018-11-20T17:23:30Z")

</div>

scripted\_upsert means the script runs whether the document already exists or not. If you want to use `docItem` as the initial document for the script to act on, maybe try passing it in as a param to the script.

---

<div class="post-metadata">

**Author:** ![Loreto\_Parisi](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/loreto_parisi/32/37830_2.png) [@Loreto\_Parisi](https://discuss.elastic.co/u/Loreto_Parisi)\
**Post date:** [November 21, 2018, 9:36am UTC](https://discuss.elastic.co/t/update-plus-with-script-in-bulk/157376/5 "2018-11-21T09:36:59Z")

</div>

> [@rjernst](#):
>
> scripted\_upsert means the script runs whether the document already exists or not. If you want to use `docItem` as the initial document for the script to act on, maybe try passing it in as a param to the script.

Thanks, it is still not clear how to do this in practice. There is no example in the docs of this use case: I want to update an existing document `docItem` or create it from scratch, and at-the-same-time I want to use the script with `scripted_upsert` so that I can append to the tag list. So supposed I will pass `docItem` in the parameters, how can I handle both cases (docItem exists, docItem new and append to to docItem['tag'] field in the script?  
Thank you.  
I have also asked here if you can provide more details - [Update index with script in ElasticSearch Bulk JavaScript API - Stack Overflow](https://stackoverflow.com/questions/53394321/update-index-with-script-in-elasticsearch-bulk-javascript-api)

---

<div class="post-metadata">

**Author:** ![rjernst](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/rjernst/32/6363_2.png) [@rjernst](https://discuss.elastic.co/u/rjernst)\
**Post date:** [November 21, 2018, 4:54pm UTC](https://discuss.elastic.co/t/update-plus-with-script-in-bulk/157376/6 "2018-11-21T16:54:10Z")

</div>

I believe the `upsert` element is still valid when doing a scripted upsert, it is just merged in with the doc _after_ the script is run. The [scripted upsert example in the docs](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html#_literal_scripted_upsert_literal) I posted before looks pretty close to what you want.

The script would contain the code to add your tags to `ctx._source`. The upsert would contain your initial document. The script will run, adding the tags, and then if the doc doesn't exist, it will be merged with the upsert element. If you have changes, then instead of passing upsert, pass the doc into your script via params. You would then need to do your own merging with a potentially already existing doc.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [December 19, 2018, 4:54pm UTC](https://discuss.elastic.co/t/update-plus-with-script-in-bulk/157376/7 "2018-12-19T16:54:13Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
