我正试图在Elasticsearch中将平均值作为一个脚本度量聚合来实现。这就是我想出来的:
{
"scripted_metric": {
"init_script": {
"source": "state.sum = 0.0; state.count = 0.0;",
"lang": "painless"
},
"map_script": {
"source": " if (doc.TradedValue.size() > 0) { state.sum += doc.TradedValue.value; state.count++; }",
"lang": "painless"
},
"combine_script": {
"source": "return state;",
"lang": "painless"
},
"reduce_script": {
"source": " double avg = 0; double c = 0; for (s in states) { avg += s.sum; c += s.count; } if (c == 0) { return 0.0; } return avg / c;",
"lang": "painless"
}
}
}这似乎有效,并产生与标准avg度量相同的结果。
然而,我担心map_script中的部分可能不正确。在我看到的所有示例中,这个脚本正在执行某种状态的.add方法,并且求和是在combine_script中完成的。
我认为这可能是由于并发问题造成的,这使得+=在map_script中不安全。是这种情况吗?还是我的剧本是对的?
发布于 2019-10-11 09:33:47
发布于 2019-10-08 16:31:13
我找到了一些推荐信。
脚本化的度量聚合在其执行的4个阶段使用脚本: init_script在任何文档收集之前执行。 map_script在每个收集的文档中执行一次。这是必需的脚本。 在完成文档收集之后,combine_script在每个碎片上执行一次。 在所有碎片返回结果之后,reduce_script在协调节点上执行一次。
使用此Map在组合脚本中添加用于处理的值。其他值必须是Map、List、String或基元类型。在给定碎片上的所有聚合文档之间共享相同的状态映射。
我认为你的案子很简单,很简单,应该很好。
但是,在复杂的场景中,我认为最好只在map上下文[2]中进行映射,并使用在每个碎片上工作的combine上下文来完成计算,因为映射状态可以在所有碎片中使用。
这是无痛源,如果有兴趣深入研究的话。
https://stackoverflow.com/questions/58289685
复制相似问题