ES 日期格式影响聚合效果
最近在使用 date_histogram
参数对日期范围聚合时,发现聚合结果不正确,分析后发现和 ES 日期格式有关,记录如下。
date_histogram
是 ES 提供针对日期属性,进行区间聚合的一种方式,比如可以对如 1 分钟,1 小时,等时间区间的文档进行聚合。
举例来说,我这里是对几天内的文档数据,按照 1 小时的时间区间进行聚合,payload 如下:
{
"size": 100,
"query": {
"range": {
"collect_time": {
"gte": 1610265800, # 开始时间
"lt": "now" # 结束时间
}
}
},
"aggs": {
"group_by_hour": {
"date_histogram": {
"field": "collect_time", # collect_time 为日期属性,按照该属性进行聚合
"interval": "hour", # 聚合的区间为小时
"format": "yyyy-MM-dd-hh" # 返回结果中的日期显示格式
},
"aggs": {
"avgrtt": {
"avg": {
"field": "avgrtt" # 聚合待求平均值的字段
}
}
}
}
}
}
按照期待的理解,返回的数据应该按照 1 小时的间隔进行返回,但实际上返回的结果却是:
"aggregations": {
"group_by_hour": {
"buckets": [
{
"key_as_string": "1970-01-19-03",
"key": 1609200000,
"doc_count": 70,
"avgrtt": {
"value": 1.0
}
}
]
}
}
传入的最小日期为 1610265800 ,也就是 2021-01-10 16:03:20. 但这里聚合后的时间结果是 1970-01-19-03。说明聚合的粒度根本不对,而且这里聚合 doc 总数也和期待的总数不一致,
后来查询 ES Date 文档后发现,ES 针对日期类型,默认的格式为:strict_date_optional_time||epoch_millis
, 也就是毫秒级别。
而之前建立 index 模板时,并未对日期属性指定 format,所以默认选择为上述毫秒格式的时间戳。但是入库的数据,时间戳为秒。
自然,在聚合时,ES 会用毫秒的格式去聚合秒的数据,导致结果都是以 1970
开始。
修改也很简单,在创建 index 模板时,显示指定为秒格式即可:
"collect_time": {
"type": "date",
"format": "epoch_second"
},
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了