1.需求
选出前5条当前响应时间最大的url数据
2.实现
用key_id分组url,在内部选出最大taskFinishTime那条数据,根据其responseTime进行排序。
对buckets数据排序,要求排序字段是个值,不能是聚合。
所以这里使用scripted_metric
统计last_response_time,就可以直接取到值。
(之前试过根据taskFinishTime排序,选出top hits 1的数据,显示其responseTime。但这种结果中有buckets,没法用作排序字段)
script中涉及:
taskFinishTime的是date
类型的,取到的doc['taskFinishTime'].value
不能直接和long类型的变量state.taskFinishTime
作比较。
所以进行转换Date->Instant->Long,Date转Long语句doc['taskFinishTime'].value.toInstant().toEpochMilli()
es语句
GET /aaa/_search
{
"size": 0,
"query": {
"bool": {
"filter": {
"range": {
"taskFinishTime": {
"gte": 1630825435000,
"lte": 1630911835000
}
}
},
"must": [
{
"exists": {
"field": "result.http_request.responseTime"
}
},
{
"exists": {
"field": "result.http_request.statusCode"
}
}
]
}
},
"aggs": {
"group_by_url": {
"terms": {
"field": "key_id.keyword",
"size": 10000
},
"aggs": {
"url_nodealias": {
"top_hits": {
"size": 1,
"_source": {
"includes": [
"nodealias"
]
}
}
},
"last_response_time": {
"scripted_metric": {
"init_script": "state.taskFinishTime = 0L; state.responseTime = 0L;",
"map_script": "if(doc['taskFinishTime'].value.toInstant().toEpochMilli() > state.taskFinishTime) {state.taskFinishTime = doc['taskFinishTime'].value.toInstant().toEpochMilli(); state.responseTime = doc['result.http_request.responseTime'].value;}",
"combine_script": "return state",
"reduce_script": "long finalTaskFinishTime = 0L; double finalResponseTime = 0L; for (a in states){if(finalTaskFinishTime < a.taskFinishTime) {finalTaskFinishTime = a.taskFinishTime; finalResponseTime = a.responseTime;}} return finalResponseTime"
}
},
"bucket_sort_temp": {
"bucket_sort": {
"sort": [
{
"last_response_time.value": {
"order": "desc"
}
}
],
"size": 5
}
}
}
}
}
}