如何使用Elasticsearch按自定义时间分桶统计指定设备的故障数量?
Elasticsearch 复杂查询实现方案
结论
完全可以通过Elasticsearch查询实现该需求,核心逻辑为自定义时间区间分桶 + 故障状态过滤 + 设备ID去重计数组合实现。
前置条件
- 数据中的
time字段为Elasticsearch原生date类型,不可为普通字符串 status字段为keyword类型,支持精准值匹配deviceId字段为keyword类型,支持去重统计
具体查询DSL
{ "query": { "bool": { "filter": [ // 过滤指定设备列表 { "terms": { "deviceId": ["001", "002", "003"] } }, // 可按需调整时间范围,限定查询的起止日期 { "range": { "time": { "gte": "2023-11-01 00:00:00", "lte": "2023-11-03 23:59:59" } } } ] } }, "size": 0, "aggs": { // 按每日10:00、22:00的时间区间分桶,key为统计时间点 "time_buckets": { "range": { "field": "time", "ranges": [ { "from": "2023-11-01 00:00:00", "to": "2023-11-01 10:00:00", "key": "Nov.1 10:00" }, { "from": "2023-11-01 10:00:00", "to": "2023-11-01 22:00:00", "key": "Nov.1 22:00" }, { "from": "2023-11-01 22:00:00", "to": "2023-11-02 10:00:00", "key": "Nov.2 10:00" }, { "from": "2023-11-02 10:00:00", "to": "2023-11-02 22:00:00", "key": "Nov.2 22:00" }, { "from": "2023-11-02 22:00:00", "to": "2023-11-03 10:00:00", "key": "Nov.3 10:00" }, { "from": "2023-11-03 10:00:00", "to": "2023-11-03 22:00:00", "key": "Nov.3 22:00" } ] }, "aggs": { // 过滤状态为fail的文档 "fail_status": { "filter": { "term": { "status": "fail" } }, "aggs": { // 去重统计故障设备数量 "error_device_count": { "cardinality": { "field": "deviceId" } } } } } } } }
结果说明
返回的聚合结果中,每个时间桶下的fail_status.error_device_count.value就是对应区间的故障设备数,和预期输出结果完全匹配。如果查询时间跨度较短,直接用上述方案即可;如果时间跨度大、需要自动生成分桶,可以参考下方扩展方案。
扩展:大时间范围自动分桶方案
手动配置range区间效率低的场景下,可以用12小时间隔的date_histogram配合偏移量自动对齐10点、22点的分桶规则,无需手动逐个配置区间:
"time_buckets": { "date_histogram": { "field": "time", "fixed_interval": "12h", "offset": "10h" // 偏移到每天10点触发分桶 }, // 后续的故障过滤、设备去重逻辑和上文一致 }
内容的提问来源于stack exchange,提问作者James Fu
相关产品推荐
相关产品推荐

