嘿~ 今天天气不错嘛

elastic多层嵌套聚合语句

Elasticsearch | 作者 liuvlun | 发布于2021年03月05日 | 阅读数:2136

elastic数据中存储了每个设备上传的抄表数据,需要对这些数据做分析展示
目的:展现每个小时的最大/最小/平均/和抄表值。
实现步骤:
1 先对抄表数据做时间聚合
2 然后对时间聚合的bucket做设备去重聚合
3 对设备去重的聚合再做top_hits聚合
经过这三个嵌套聚合能够获取每个时间段每个设备最接近整点的数据,然后在java程序中做最大/最小/平均的计算。但是这样操作会造成elastic形成很多的bukets,超过了最大的buckets数量,但是elastic又不允许改这些配置,如何能做到直接在elastic做这些最大/最小/平均的聚合?

现在的es的语句写法如下:
{
"size": 0,
"query": {
"bool": {
"must": [
{
"range": {
"ts": {
"from": 1612400400000,
"to": 1612404000000,
"include_lower": true,
"include_upper": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"_source": false,
"aggregations": {
"histName": {
"date_histogram": {
"field": "ts",
"fixed_interval": "1h",
"offset": -1800000,
"order": {
"_key": "asc"
},
"keyed": false,
"min_doc_count": 0,
"extended_bounds": {
"min": 1612400400000,
"max": 1612404000000
}
},
"aggregations": {
"dId": {
"terms": {
"field": "dId",
"size": 5000,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_key": "asc"
}
]
},
"aggregations": {
"topHitsName": {
"top_hits": {
"from": 0,
"size": 1,
"version": false,
"seq_no_primary_term": false,
"explain": false,
"sort": [
{
"_script": {
"script": {
"source": "long s = doc['ts'].value.toInstant().toEpochMilli() % 3600000L;return (s >= 1800000L ? 3600000L - s : s);",
"lang": "painless"
},
"type": "number",
"order": "asc"
}
}
]
}
}
}
}
}
}
}
}
已邀请:

FFFrp

赞同来自:

能把设备号+小时作为ID写到一个索引里面吗,你这个取每个时间段每个设备最接近整点的数据如果不是或递减的感觉不要好查询,另外就是你上面query指定了一个小时,下面就不用时间聚合了吧

codersun

赞同来自:

你最终的需求是获取一条数据,可以试试 top_metrics。
预先构造一个字段,表示文档与整点的距离,使用top_metrics获取距离最短的一个文档。
设备数的buckets超出1w,这个就没办法了,一定要用的话,可以改配置调高buckets限制数量

要回复问题请先登录注册