弹性聚合以识别时期 A 与时期 B 百分比增加
Elastic aggregation to identify period A vs B percentage increases
我将一些日常销售数据编入了 Elasticsearch 索引。我成功地 运行 一些聚合来识别日期范围内的畅销书等。
我现在正在尝试编写一个查询来执行以下操作:
- 确定日期范围内(时间段 A)的前 n 个卖家
- 获取期间 A 的结果并计算这些产品在第二个日期范围内(期间 B)的销售额
- 比较 A 期和 B 期的销售额,找出百分比增长超过 X% 的销售额。
我目前的尝试:
{
"query": {
"bool": {
"filter": [
{
"range": {
"date": {
"gte": "2017-10-01",
"lte": "2017-10-14"
}
}
}
]
}
},
"size": 0,
"aggs": {
"data_split": {
"terms": {
"size": 10,
"field": "product_id"
},
"aggs": {
"date_periods": {
"date_range": {
"field": "date",
"format": "YYYY-MM-dd",
"ranges": [
{
"from": "2017-10-01",
"to": "2017-10-07"
},
{
"from": "2017-10-08",
"to": "2017-10-14"
}
]
},
"aggs": {
"product_id_split": {
"terms": {
"field": "product_id"
},
"aggs": {
"unit_sum": {
"sum": {
"field": "units"
}
}
}
}
}
}
}
}
}
}
尽管这会输出两个时间段的结果,但我认为这不是我想要的,因为初始过滤器是从时间段 A 开始日期到时间段 B 结束日期 运行ning 并且我认为求和结果对于该范围而不是仅针对期间 A。我也没有得到百分比比较,我可能会在我的应用程序级别执行此操作,但我知道可以使用脚本化弹性查询来处理吗?
如果不是 A 期的前 n 个结果,我可以设置一个销售阈值,比如 1,000 个销售量,那就太棒了。
任何指点将不胜感激。提前致谢!
当前 运行ning Elastic 5.6
{
"query": {
"bool": {
"filter": [
{
"range": {
"date": {
"gte": "2017-10-01",
"lte": "2017-10-14"
}
}
}
]
}
},
"size": 0,
"aggs": {
"data_split": {
"terms": {
"size": 10,
"field": "product_id"
},
"aggs": {
"date_period1": {
"filter": {
"range": {
"date": {
"gte": "2017-10-01",
"lte": "2017-10-07"
}
}
},
"aggs": {
"unit_sum": {
"sum": {
"field": "units"
}
}
}
},
"date_period2": {
"filter": {
"range": {
"date": {
"gte": "2017-10-08",
"lte": "2017-10-14"
}
}
},
"aggs": {
"unit_sum": {
"sum": {
"field": "units"
}
}
}
},
"percentage_increase": {
"bucket_script": {
"buckets_path": {
"firstPeriod": "date_period1>unit_sum",
"secondPeriod": "date_period2>unit_sum"
},
"script": "(params.secondPeriod-params.firstPeriod)*100/params.firstPeriod"
}
},
"retain_buckets": {
"bucket_selector": {
"buckets_path": {
"percentage": "percentage_increase"
},
"script": "params.percentage > 5"
}
}
}
}
}
}
还有一个完整的测试数据在这个gist.
聚合的结果是:
"aggregations": {
"data_split": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "A",
"doc_count": 6,
"date_period1": {
"doc_count": 3,
"unit_sum": {
"value": 150
}
},
"date_period2": {
"doc_count": 3,
"unit_sum": {
"value": 160
}
},
"percentage_increase": {
"value": 6.666666666666667
}
},
{
"key": "C",
"doc_count": 2,
"date_period1": {
"doc_count": 1,
"unit_sum": {
"value": 50
}
},
"date_period2": {
"doc_count": 1,
"unit_sum": {
"value": 70
}
},
"percentage_increase": {
"value": 40
}
}
]
}
}
我们的想法是对两个日期间隔使用两种 filter
类型的聚合。并为每个计算总和。然后,使用 bucket_script
类型的第三个聚合计算百分比增长(但请注意,例如销售额下降,它将是负数)。
然后,使用另一个聚合 - bucket_selector
类型 - 你保留百分比大于 5% 的 product_id
s。
我将一些日常销售数据编入了 Elasticsearch 索引。我成功地 运行 一些聚合来识别日期范围内的畅销书等。
我现在正在尝试编写一个查询来执行以下操作:
- 确定日期范围内(时间段 A)的前 n 个卖家
- 获取期间 A 的结果并计算这些产品在第二个日期范围内(期间 B)的销售额
- 比较 A 期和 B 期的销售额,找出百分比增长超过 X% 的销售额。
我目前的尝试:
{
"query": {
"bool": {
"filter": [
{
"range": {
"date": {
"gte": "2017-10-01",
"lte": "2017-10-14"
}
}
}
]
}
},
"size": 0,
"aggs": {
"data_split": {
"terms": {
"size": 10,
"field": "product_id"
},
"aggs": {
"date_periods": {
"date_range": {
"field": "date",
"format": "YYYY-MM-dd",
"ranges": [
{
"from": "2017-10-01",
"to": "2017-10-07"
},
{
"from": "2017-10-08",
"to": "2017-10-14"
}
]
},
"aggs": {
"product_id_split": {
"terms": {
"field": "product_id"
},
"aggs": {
"unit_sum": {
"sum": {
"field": "units"
}
}
}
}
}
}
}
}
}
}
尽管这会输出两个时间段的结果,但我认为这不是我想要的,因为初始过滤器是从时间段 A 开始日期到时间段 B 结束日期 运行ning 并且我认为求和结果对于该范围而不是仅针对期间 A。我也没有得到百分比比较,我可能会在我的应用程序级别执行此操作,但我知道可以使用脚本化弹性查询来处理吗?
如果不是 A 期的前 n 个结果,我可以设置一个销售阈值,比如 1,000 个销售量,那就太棒了。
任何指点将不胜感激。提前致谢!
当前 运行ning Elastic 5.6
{
"query": {
"bool": {
"filter": [
{
"range": {
"date": {
"gte": "2017-10-01",
"lte": "2017-10-14"
}
}
}
]
}
},
"size": 0,
"aggs": {
"data_split": {
"terms": {
"size": 10,
"field": "product_id"
},
"aggs": {
"date_period1": {
"filter": {
"range": {
"date": {
"gte": "2017-10-01",
"lte": "2017-10-07"
}
}
},
"aggs": {
"unit_sum": {
"sum": {
"field": "units"
}
}
}
},
"date_period2": {
"filter": {
"range": {
"date": {
"gte": "2017-10-08",
"lte": "2017-10-14"
}
}
},
"aggs": {
"unit_sum": {
"sum": {
"field": "units"
}
}
}
},
"percentage_increase": {
"bucket_script": {
"buckets_path": {
"firstPeriod": "date_period1>unit_sum",
"secondPeriod": "date_period2>unit_sum"
},
"script": "(params.secondPeriod-params.firstPeriod)*100/params.firstPeriod"
}
},
"retain_buckets": {
"bucket_selector": {
"buckets_path": {
"percentage": "percentage_increase"
},
"script": "params.percentage > 5"
}
}
}
}
}
}
还有一个完整的测试数据在这个gist.
聚合的结果是:
"aggregations": {
"data_split": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "A",
"doc_count": 6,
"date_period1": {
"doc_count": 3,
"unit_sum": {
"value": 150
}
},
"date_period2": {
"doc_count": 3,
"unit_sum": {
"value": 160
}
},
"percentage_increase": {
"value": 6.666666666666667
}
},
{
"key": "C",
"doc_count": 2,
"date_period1": {
"doc_count": 1,
"unit_sum": {
"value": 50
}
},
"date_period2": {
"doc_count": 1,
"unit_sum": {
"value": 70
}
},
"percentage_increase": {
"value": 40
}
}
]
}
}
我们的想法是对两个日期间隔使用两种 filter
类型的聚合。并为每个计算总和。然后,使用 bucket_script
类型的第三个聚合计算百分比增长(但请注意,例如销售额下降,它将是负数)。
然后,使用另一个聚合 - bucket_selector
类型 - 你保留百分比大于 5% 的 product_id
s。