I'm trying to write a script that will upsert a new user record to ElasticSearch, updating any information if the user already exists, and appending a new PaymentInfo object to the user's Payments array if it exists in the update object. Here's a simplified version of what I'm working with so far:
curl -XPOST 'http://localhost:9200/usrtest/usr/1/_update' -d '
{
"doc_as_upsert": true,
"doc": {
"customerId": "1",
"firstName": "Mark",
"lastName": "Z",
"emailAddress": "[email protected]",
"paymentInfo": {
"pid": "1",
"amt": "10"
}
}
}'
This almost does what I want in that it inserts the doc properly, or updates the doc if a user exists with the same ID, but it's missing the aspect to add this paymentInfo to the user's paymentInfos array if the user exists already. As it is right now, it just overrides the paymentInfo object. I've tried adding this script to the update JSON:
"script": "if (ctx._source.containsKey("paymentInfos")) {ctx._source.paymentInfos += paymentInfo;} else {ctx._source.paymentInfos = paymentInfo}"
but elasticsearch ignores doc
elements when the script
element is specified.
I feel like I'm missing something silly here, but I'm not sure. Can anyone here help me out?
Edit:
I've tried the following as well:
curl -XPOST 'http://localhost:9200/usrtest/usr/1/_update' -d '
{
"script": "if (ctx._source.containsKey("paymentInfos")) {ctx._source.paymentInfos += paymentInfo;} else {ctx._source.paymentInfos = paymentInfo}",
"upsert": {
"customerId": "1",
"firstName": "Mark",
"lastName": "Z",
"emailAddress": "[email protected]",
"paymentInfo": {
"pid": "1",
"amt": "10"
}
},
"params": {
"paymentInfo": {
"pid": "1",
"amt": "10"
}
}
}'
Which also almost does what I want it to, in that it appends the paymentInfo objects when I run the script several times, but otherwise it doesn't update the document itself (i.e. if I run the script again, changing Mark to Mindy, it doesn't update since upsert
elements are only used if the doc doesn't exist already).
See Question&Answers more detail:
os