簡體   English   中英

用於生成嵌套字段的Elasticsearch Groovy腳本語法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM