The below simple ES Groovy script takes a python dictionary with order data (orderItem) and appends it to a list of orders within Elasticsearch. The list with all orderItems then resides under _source.Orders
"script": "if (ctx._source.containsKey(\"Orders\")) {ctx._source.Orders += orderItem;} else {ctx._source.Orders = [orderItem]}; "
"params":{"orderItem": orderItem}
In my use case, orders come from different shops and want them to go in to a list structure under _source.Orders.Shop5Hgk, _source.Orders.Shop86hG, _source.Orders.Shop5G60, etc. The shop names are dynamic.
No matter, what I try, ES throws exceptions complaining that Orders obviously is null.
GroovyScriptExecutionException[NullPointerException[Cannot set property 'Shop5Hgk' on null object]
So, what is the right groovy syntax to create the Orders field first, and then the field for the shop name and then append orderItems to that?
Update: Full python function with (not working)
def updateLastOrdersElasticsearch(self,data):
es = elasticsearch.Elasticsearch(timeout=500)
actions = []
for shopName,orderList in data.items():
for orderItem in orderList:
sku = orderItem['SKU']
action = {
"_index": "myindex",
"script": "if (ctx._source.containsKey(\"Orders\")) {if (ctx._source.containsKey(shopName)){ctx._source.Orders."+shopName+" += Orders;}} else {ctx._source.Orders = []; ctx._source.Orders."+shopName+" = [Orders]}; ctx._source.TimestampUpdated = TimestampUpdated",
"_type": "items",
'_op_type': 'update',
"_id": sku,
"params":{"shopName":shopName,"Orders": orderItem, "TimestampUpdated":datetime.now().isoformat()}
}
actions.append(action)
return helpers.bulk(es, actions)