Create structure in painless update script

I am using Elasticsearch 6.5.
I want to use an update API with the painless script. Let's say, that my target document has an address structure inside of it. Update script may look something like this:

ctx._source.address.street = params.src.address.street;   
ctx._source.address.city = params.src.address.city;   
ctx._source.address.postal_code = params.src.address.postal_code; 

Which usually runs great. But there are documents, that do not have an address structure. In these cases update script fails with null_pointer_exception error - then I am addressing inner field of not existing structure.

So basically my questions are:

  1. How to detect in painless, that document does not have an address structure?
  2. How to create this inner structure and set values to it?

To answer questions that may arise: making the whole document flat (just fields without inner structure) is not an option in my case. Also, I cannot modify documents to ensure, that everyone has an address structure, before an update script.

Ok,
I managed to detect if address structure exist with:

if (ctx._source.address != null) { (...) }

But still I have no idea how to create this structure.

I tried the following:

POST test_idx1/_doc/1/_update
{
    "script": """ 
        if (ctx._source.address != null) {
            ctx._source.address.street = params.src.street;
            ctx._source.address.city = params.src.city;
            ctx._source.address.postal_code = params.src.postal_code;
        } else {
            ctx._source.address = params.src;
        }
        """,
    "params": {
    "src": 
        {
            "street" : "test str",
            "city": "London",
            "postal_code": "01-234"
        }
    }
}

But in the result the address field is created, but has null value.

Ok, I cannot delete the thread, so I will post the solution.
The syntax was wrong. The correct one is below:

POST test_idx1/_doc/1/_update
{
    "script": {
    "source" : """ 
        if (ctx._source.address != null) {
            ctx._source.address.street = params.src.street;
            ctx._source.address.city = params.src.city;
            ctx._source.address.postal_code = params.src.postal_code;
        } else {
            ctx._source.address = params.src;
        }
        """,
    "params": {
    "src": 
        {
            "street" : "test str",
            "city": "London",
            "postal_code": "01-234"
        }
    }
  }
}

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