ES6.0.0官方參考指南翻譯~指標聚合~Scripted Metric Aggregation

警告

該功能目前處於試驗階段,因此有可能將來會發生改變或刪除.

該指標聚合會使用腳本來提供指標輸出。

例如:

POST ledger/_search?size=0

{

"query" : {

"match_all" : {}

},

"aggs": {

"profit": {

"scripted_metric": {

"init_script" : "params._agg.transactions = []",

"map_script" : "params._agg.transactions.add(doc.type.value == 'sale' ? doc.amount.value : -1 * doc.amount.value)", #1

"combine_script" : "double profit = 0; for (t in params._agg.transactions) { profit += t } return profit",

"reduce_script" : "double profit = 0; for (a in params._aggs) { profit += a } return profit"

}

}

}

}

1:map_script是唯一所需參數

上述聚合演示瞭如何使用腳本聚合來計算銷售與成本間的總利潤。

上述聚合的響應為:

{

"took": 218,

...

"aggregations": {

"profit": {

"value": 240.0

}

}

}

上面的示例也可以使用存儲腳本指定,如下所示:

POST ledger/_search?size=0

{

"aggs": {

"profit": {

"scripted_metric": {

"init_script" : {

"id": "my_init_script"

},

"map_script" : {

"id": "my_map_script"

},

"combine_script" : {

"id": "my_combine_script"

},

"params": {

"field": "amount", #1

"_agg": {} #2

},

"reduce_script" : {

"id": "my_reduce_script"

}

}

}

}

}

1:必須在全局params對象中指定init,map和combine腳本的腳本參數,以便它們可以在腳本之間共享。

2:如果指定了腳本參數,那麼必須同時指定"_agg": {}.

有關腳本的用法 ,請參考script documentation.

返回類型

雖然任何有效腳本對象都可以在單個腳本中使用,但腳本只能返回如下類型中返回(存儲在_agg對象中的類型也有此限制):

  • 原始類型
  • String
  • Map (僅包含此處列出的鍵和值類型)
  • Array (包含僅此處列出的元素類型)

腳本範圍

腳本指標聚合在執行時存在4個階段:

init_script

在收集文檔前執行。允許聚合設置任何初始狀態。在上面的示例中,init_script 在_agg 對象中創建了一個transactions數組.

map_script

對每個文檔調用一次。這是唯一所需的腳本。如果未指定combine_script,則生成的狀態需要存儲在名為_agg的對象中。

在上面的示例中,map_script會檢查type字段的值。如果值是sale,那麼會將amount字段的值加到transactions數組中,反之則將amount字段的負值加到transactions中.

combine_script

在文檔收收集完後會在每個分片上執行一次。它允許合併從每個分片返回的狀態。

如果未提供combine_script,則組合階段會返回_aggs變量。

在上面的示例中,combine_script遍歷所有存儲的交易,對profile進行求和,並最終返回這個profit.

reduce_script

在所有分片返回結果後,只在協調節點上執行一次。該腳本提供了對變量_aggs的訪問權限,該變量是每個分片上combine_script計算結果的數組。如果未提供reduce_script,則reduce階段將返回_aggs變量。

在上面的示例中,reduce_script會遍歷每個分片上返回的profit,然後再對這些profit進行累加,最後以聚合響應的形式返回累加結果.

工作示例

假設我們將以下文檔索引到包含2個分片的索引中:

PUT /transactions/stock/_bulk?refresh

{"index":{"_id":1}}

{"type": "sale","amount": 80}

{"index":{"_id":2}}

{"type": "cost","amount": 10}

{"index":{"_id":3}}

{"type": "cost","amount": 30}

{"index":{"_id":4}}

{"type": "sale","amount": 130}

假設文檔1和3分在了分片A上,文檔2和4分在分片B上.

下面是上述示例中每個階段的詳細步驟信息。

在init_script之前

未指定任何參數對象,因此會使用默認參數對象:

"params" : {

"_agg" : {}

}

在init_script之後

這會在每個分片上運行一次,然後才會執行文檔收集,因此我們將在每個分片上有一個副本:

Shard A

"params" : {

"_agg" : {

"transactions" : []

}

}

Shard B

"params" : {

"_agg" : {

"transactions" : []

}

}

在map_script之後

每個分片都會收集相關文檔,並對每個收集文檔運行map_script:

Shard A

"params" : {

"_agg" : {

"transactions" : [ 80, -30 ]

}

}

Shard B

"params" : {

"_agg" : {

"transactions" : [ -10, 130 ]

}

}

在combine_script之後

文檔收集完成後,會在每個分片上執行combine_script,並將所有交易redice到每個分片的單個profit中(通過對transactions數組中的值求和),最後再將其傳回協調節點:

Shard A

50

Shard B

120

在reduce_script之後

reduce_script接收一個_aggs數組,數組中每個元素都是每個分片上combine_script的執行結果:

"_aggs" : [

50,

120

]

它會將分片響應縮減到最終的利潤(pfofit)數字(通過求和),並將其作為最終聚合結果來生成響應:

{

...

"aggregations": {

"profit": {

"value": 170

}

}

}

其它參數

params

可選.其參數內容會作為變量傳遞給init_script, map_script和combine_script.

該參數對於控制聚合行為以在腳本間的狀態存儲非常有用.如果未指定,則默認等價於:

"params" : {

"_agg" : {}

}

空桶

如果腳本指標聚合的父桶未收集到任何文檔,那麼帶有空null值的分片會返回空聚合響應。

在這種情況下,reduce_script的_aggs變量會返回null(作為該分片的響應)。

因此,reduce_script須處理來自分片的null響應。

全部指標聚合,請參考

單值指標聚合

多值指標聚合

地理位置相關聚合

可執行Map-Reduce計算的聚合


分享到:


相關文章: