问题描述:有个聚合的需求,问下大家,一个索引中有时间字段 要求 计算本月和上月相比的环比上升比例?——来自GPVIP群
环比是统计学术语,表示连续2个统计周期内的量的变化比。
其实这个问题比较大,从大的角度讲:Elasticsearch 更适合做检索,能做脚本计算处理,但会有性能问题。
官方明确强调:
Avoid script——If possible, avoid using script-based sorting, scripts in aggregations, and the script_score query.
通俗点说,避免使用脚本,除非特殊情况必须使用。
Elasticsearch 能支持的计算问题如下几种方式:
预处理参见:
回归我们的问题,分两个维度拆解。
也就是说,汇总结果数据,需要我们借助聚合实现。
最终结果需要临近的两个月份的汇总结果计算求得,需要借助:bucket_script 子聚合实现。而bucket_script 需要两重聚合,且嵌套到内层实现。
可以通过如下三个步骤实现,如下脑图梳理。
聚合的实现是问题求解的关键。
按照上面脑图拆解的三个步骤搞定实现。视频如下:
DELETE test-20221109
PUT test-20221109
{
"mappings": {
"properties": {
"insert_date": {
"type": "date"
},
"count": {
"type": "integer"
}
}
}
}
POST test-20221109/_bulk
{"index":{"_id":1}}
{"insert_date":"2022-11-09T12:00:00Z","count":5}
{"index":{"_id":2}}
{"insert_date":"2022-11-08T12:00:00Z","count":150}
{"index":{"_id":3}}
{"insert_date":"2022-12-09T12:00:00Z","count":33}
{"index":{"_id":4}}
{"insert_date":"2022-12-08T12:00:00Z","count":44}
{"index":{"_id":5}}
{"insert_date":"2022-12-09T12:00:00Z","count":55}
{"index":{"_id":6}}
{"insert_date":"2022-12-08T12:00:00Z","count":66}
POST test-20221109/_search
{
"size": 0,
"aggs": {
"range_aggs": {
"range": {
"field": "insert_date",
"format": "yyyy-MM-dd",
"ranges": [
{
"from": "2022-11-01",
"to": "2022-12-31"
}
]
},
"aggs": {
"11month_count": {
"filter": {
"range": {
"insert_date": {
"gte": "2022-11-01",
"lte": "2022-11-30"
}
}
},
"aggs": {
"sum_aggs": {
"sum": {
"field": "count"
}
}
}
},
"12month_count": {
"filter": {
"range": {
"insert_date": {
"gte": "2022-12-01",
"lte": "2022-12-31"
}
}
},
"aggs": {
"sum_aggs": {
"sum": {
"field": "count"
}
}
}
},
"bucket_division": {
"bucket_script": {
"buckets_path": {
"pre_month_count": "11month_count > sum_aggs",
"cur_month_count": "12month_count > sum_aggs"
},
"script": "(params.cur_month_count - params.pre_month_count) / params.pre_month_count"
}
}
}
}
}
}
求解结果如下:
其实这个聚合实现相当复杂,且不够灵活,可扩展性不强。
业务选型层面,如果非实时求解的场景,真的不建议这么做。
我们可以定时离线计算结果统计,借助 Java 或者 python 等代码实现更为顺畅和“丝滑”。
你的业务层面有没有遇到类似问题?欢迎留言说一下你的方案。
1、全网首发!从 0 到 1 Elasticsearch 8.X 通关视频
本文分享自 铭毅天下Elasticsearch 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!