gpt4 book ai didi

Elasticsearch:可以处理聚合结果吗?

转载 作者:行者123 更新时间:2023-11-29 02:54:44 25 4
gpt4 key购买 nike

我使用 SUM-Aggregation 计算我的服务流程的持续时间。执行流程的每一步都将保存在 Elasticsearch 中的调用 Id 下。

这是我监控的:

Duration of Request-Processing for ID #123 (calling service #1)

Duration of Server-Response for ID #123 (calling service #1)

**Complete Duration for ID #123**

Duration of Request-Processing for ID #124 (calling service #1)

Duration of Server-Response for ID #124 (calling service #1)

**Complete duration for ID #124**

过滤器:

{
"from" : 0, "size" :0,

"query" : {
"filtered" : {
"query" : { "match_all" : {}},
"filter" : {
"term" : {
"callingId" : "123",
}
}
}
},
"aggs" : {
"total_duration" : { "sum" : { "field" : "duration" } },
"max_duration":{"max": {"field":"duration"}},
"min_duration":{"min":{"field":"duration"}}
}
}
}

这会返回流程的完整持续时间,还会告诉我流程的哪个部分最快,哪个部分最慢。

接下来我想通过 serviceId 计算平均所有已完成进程的持续时间。在这种情况下,我只关心每项服务的总持续时间,因此我可以比较它们。

如何根据我的 total_durations 创建平均值、最小值和最大值?

编辑:我添加了一些示例数据,希望您能使用它。

调用 1:

{
"callerId":"U1",
"operation":"Initialize",
"status":"INITIALIZED",
"duration":1,
"serviceId":"1"
}

{
"callerId":"U1",
"operation":"Calculate",
"status":"STARTED",
"duration":1,
"serviceId":"1"
}

{
"callerId":"U1",
"operation":"Finish",
"status":"FINISHED",
"duration":1200,
"serviceId":"1"
}

sum: 1202

调用 2:

{
"callerId":"U2",
"operation":"Initialize",
"status":"INITIALIZED",
"duration":2,
"serviceId":"1"
}

{
"callerId":"U2",
"operation":"Calculate",
"status":"STARTED",
"duration":1,
"serviceId":"1"
}

{
"callerId":"U2",
"operation":"Finish",
"status":"FINISHED",
"duration":1030,
"serviceId":"1"
}

sum: 1033

服务 ID #1 的所有服务调用的聚合这就是我要计算的:

Max: 1202
Min: 1033
AVG: 1116

最佳答案

有点复杂,但就这样了(因为 this type of aggregation 只在 1.4 中):

{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"term": {
"serviceId": 1
}
}
}
},
"aggs": {
"executionTimes": {
"scripted_metric": {
"init_script": "_agg['values'] = new java.util.HashMap();",
"map_script": "if (_agg.values[doc['callerId'].value]==null) {_agg.values[doc['callerId'].value]=doc['duration'].value;} else {_agg.values[doc['callerId'].value].add(doc['duration'].value);}",
"combine_script":"someHashMap = new java.util.HashMap();for(x in _agg.values.keySet()) {value=_agg.values[x]; sum=0; for(y in value) {sum+=y}; someHashMap.put(x,sum)}; return someHashMap;",
"reduce_script": "finalArray = []; finalMap = new java.util.HashMap(); for(map in _aggs){for(x in map.keySet()){if(finalMap.containsKey(x)){value=finalMap.get(x);finalMap.put(x,value+map.get(x));} else {finalMap.put(x,map.get(x))}}}; finalAvgValue=0; finalMaxValue=-1; finalMinValue=-1; for(key in finalMap.keySet()){currentValue=finalMap.get(key);finalAvgValue+=currentValue; if(finalMinValue<0){finalMinValue=currentValue} else if(finalMinValue>currentValue){finalMinValue=currentValue}; if(currentValue>finalMaxValue) {finalMaxValue=currentValue}}; finalArray.add(finalMaxValue); finalArray.add(finalMinValue); finalArray.add(finalAvgValue/finalMap.size()); return finalArray",
"lang": "groovy"
}
}
}
}

此外,我并不是说这是最好的方法,只是我能找到的一种方法。另外,我并不是说解决方案是最佳形式。可能,它可能会被清理和改进。不过,我想证明这是可能的。不过请记住,它在 1.4 中可用。

该方法的基本思想是使用脚本构建一个数据结构,该数据结构应包含您需要的信息,并根据 scripted metric aggregation 在不同的步骤中进行计算。 .此外,聚合仅针对一个 serviceId 执行。如果您想对所有 serviceId 执行此操作,我想您可能需要重新考虑一下脚本中的数据结构。

对于上面的查询和您提供的确切数据,输出是这样的:

{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 6,
"max_score": 0,
"hits": []
},
"aggregations": {
"executionTimes": {
"value": [
1202,
1033,
"1117.5"
]
}
}
}

根据 reduce_script 中的脚本,数组 value 中值的顺序是 [max, min, avg]。

关于Elasticsearch:可以处理聚合结果吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26992154/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com