[英]Elasticsearch Groovy Script Syntax for generation of nested fields
以下簡單的ES Groovy腳本采用帶有訂單數據(orderItem)的python字典,並將其附加到Elasticsearch內的訂單列表中。 然后,所有orderItems的列表都位於_source.Orders下
"script": "if (ctx._source.containsKey(\"Orders\")) {ctx._source.Orders += orderItem;} else {ctx._source.Orders = [orderItem]}; "
"params":{"orderItem": orderItem}
在我的用例中,訂單來自不同的商店,希望它們進入_source.Orders.Shop5Hgk,_source.Orders.Shop86hG,_source.Orders.Shop5G60等下的列表結構。商店名稱是動態的。
沒關系,無論如何,ES都會拋出異常,抱怨Orders顯然為空。
GroovyScriptExecutionException [NullPointerException [無法在空對象上設置屬性'Shop5Hgk']
那么,首先創建Orders字段,然后創建商店名稱的字段,然后將orderItems附加到該字段的正確的常規語法是什么?
更新:完整的python功能(不起作用)
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)
我認為最初您的_source.Orders
字段為null,即什至不是一個空數組。
此外, containsKey
可能不是正確的方法,因為_source
可能包含一個名為Orders
的字段,其類型可能不是數組,即它可能是代表現有訂單的動態對象,或更糟糕的是,它只是一個純字符串。
我建議您通過先檢查Orders
是否為null並嘗試將其初始化為空數組來嘗試另一種方法。 然后,您可以將orderItem
附加到結果數組:
{
"script" : "ctx._source.Orders = ((ctx._source.Orders ?: []) += orderItem)",
"params" : {
"orderItem" : orderItem
}
}
替代方法是僅確保首次索引文檔時,確保使用空數組[]
初始化Orders
字段,然后腳本可以簡單地將orderItems
追加到該數組。
更新
根據您的評論,我正在修改我的答案,以處理“ Orders
是一個動態對象,其中包含商店名稱作為關鍵字,並且每個關鍵字都指向該商店的訂單數組的情況。 這與之前的想法基本相同,只是我們需要再處理一個級別(即商店名稱)。
首先,腳本確保Orders
對象存在,然后確保Orders
對象內的shop數組也存在。 剩下要做的就是將orderItem
附加到shop數組:
{
"script" : "ctx._source.Orders = ctx._source.Orders ?: [shopName:'']; ctx._source.Orders[shopName] = ((ctx._source.Orders[shopName] ?: []) + orderItem); ctx._source.TimestampUpdated = TimestampUpdated",
"params" : {
"shopName": shopName,
"orderItem" : orderItem,
"TimestampUpdated":datetime.now().isoformat()
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.