ElasticSearch 2.4中date_histogram间隔转秒计算速率的方法
解决Elasticsearch 2.4中date_histogram间隔的秒数转换问题
针对你在Elasticsearch 2.4里计算雨滴平均速率的需求,其实可以通过Groovy脚本结合ES内置的时间单位工具类自动将配置的interval转换成秒数,完全不需要手动预先转换。具体方案如下:
核心思路
- 把
date_histogram的interval值作为参数传入bucket_script,避免硬编码导致的不一致; - 借助ES内置的
org.elasticsearch.common.unit.TimeValue类,将间隔字符串(比如"0.5h")解析为毫秒数,再转成秒数; - 用雨滴总数除以间隔秒数,得到单位时间内的平均速率。
修改后的完整查询
{ "query": { ... }, "aggregations": { "by_hour": { "date_histogram": { "field": "timestamp", "interval": "0.5h", "extended_bounds": { "min": "now/d-5h", "max": "now/d-1h" } }, "aggregations": { "sum_raindrops": { "sum": { "field": "raindrops_seen" } }, "avg_raindrop_rate": { "bucket_script": { "buckets_path": { "var_sum_raindrops": "sum_raindrops" }, "params": { "interval_str": "0.5h" // 这里和date_histogram的interval保持一致 }, "script": "def intervalMillis = org.elasticsearch.common.unit.TimeValue.parseTimeValue(params.interval_str, 'interval').getMillis(); def intervalSeconds = intervalMillis / 1000; return var_sum_raindrops / intervalSeconds;" } } } } } }
关键细节说明
- 时间单位解析:
TimeValue.parseTimeValue()是ES原生的工具方法,完全支持官方定义的所有时间单位(比如"0.5h"、"1d"、"30m"、"2w"等),getMillis()能直接拿到对应的毫秒数; - 参数一致性:务必保证
params.interval_str和date_histogram里的interval完全相同,这样计算出的速率才准确; - 版本兼容性:Elasticsearch 2.4默认使用Groovy脚本,这个写法在该版本下完全兼容,不需要额外调整脚本配置。
如果担心重复写interval容易出错,也可以通过Mustache模板化查询来统一管理这个参数,调用查询时传入对应值即可。
内容的提问来源于stack exchange,提问作者Prismatic
相关产品推荐
相关产品推荐

