聚合结果的 Elasticsearch 过滤器(用于搜索和聚合)
Elasticsearch filter on aggregation result (for search and aggregation)
部分问题与:Elasticsearch filter on aggregation
上下文
假设我的 Elasticsearch 索引包含一些订单。每个订单都有一个字段价格和一个字段金额。这导致索引看起来像这样:
[
{
"docKey": "order01",
"user": "1",
"price": 8,
"amount": 20
},
{
"docKey": "order02",
"user": "1",
"price": 14,
"amount": 3
},
{
"docKey": "order03",
"user": "2",
"price": 5,
"amount": 1
},
{
"docKey": "order04",
"user": "2",
"price": 10,
"amount": 3
}
]
我想做什么
我想要做的是对每个用户聚合的一些值进行过滤。我想为搜索做这种过滤器,也是为了在其上应用聚合。例如,在此示例中,我想检索平均订单价格在 9-14 范围内的所有用户的文档。
用户 1 的平均价格订单为 11,因此我们保留他的两个订单。
用户 2 的平均价格订单为 7.5,因此他的两个订单均未保留。
这是简单的部分。在我过滤后只得到用户一个。我想对结果做更多的聚合。
因此,例如:我希望为所有平均订单价格在范围内的用户重新分配存储桶 [0,10] 和 [10,20] 中 amout 字段的每个用户的平均值9-14.
我除了这个问题的答案是[0,10]桶中的0个和[10,20]桶中的一个(只保留用户1,因为他的平均价格。他的平均金额是11.5所以在存储桶 [10,20]) 中。
我试过的
我已经设法对我的过滤器进行操作,以检索平均订单价格在 9-14 范围内的用户。我通过首先对用户提交的术语聚合来做到这一点。然后我做一个子聚合,它是价格的平均聚合。然后我进行桶选择器管道聚合,检查先前计算的平均价格是否在 9 到 14 之间。
我也设法进行了我想要的聚合,但没有以前的过滤器。我为每个范围的过滤器做了完全相同的事情。然后我计算每个桶中的结果数。
我还没有找到任何方法来对存储桶选择器结果应用其他聚合。所以我不能先做过滤器然后再应用范围...
此外,这些解决方案也不优雅。我认为它们不会扩大,因为文档的很大一部分需要在答案中返回并进一步处理(即使它不在互联网上,我更愿意避免这样做我可能在聚合的结果大小方面受到限制?)。
我设法找到了解决方案,但它不够优雅,而且可扩展性可能很差。
- 对用户进行术语聚合。
- 作为术语聚合的子聚合,执行计算价格平均值的平均聚合。
作为术语聚合的子聚合,执行计算金额平均值的平均聚合。
执行桶选择器管道聚合,过滤以仅将 avg_price 保持在 [9-14] 范围内。
- 执行桶选择器管道聚合,过滤以仅将 avg_amount 保留在 [0-10]
中
- 执行 "count" 存储桶脚本管道聚合(脚本返回一个)。
- 对计数求和的桶总和管道聚合。
- 对所有想要的范围重复所有步骤([0-10]、[10-20])
部分问题与:Elasticsearch filter on aggregation
上下文
假设我的 Elasticsearch 索引包含一些订单。每个订单都有一个字段价格和一个字段金额。这导致索引看起来像这样:
[
{
"docKey": "order01",
"user": "1",
"price": 8,
"amount": 20
},
{
"docKey": "order02",
"user": "1",
"price": 14,
"amount": 3
},
{
"docKey": "order03",
"user": "2",
"price": 5,
"amount": 1
},
{
"docKey": "order04",
"user": "2",
"price": 10,
"amount": 3
}
]
我想做什么
我想要做的是对每个用户聚合的一些值进行过滤。我想为搜索做这种过滤器,也是为了在其上应用聚合。例如,在此示例中,我想检索平均订单价格在 9-14 范围内的所有用户的文档。
用户 1 的平均价格订单为 11,因此我们保留他的两个订单。 用户 2 的平均价格订单为 7.5,因此他的两个订单均未保留。
这是简单的部分。在我过滤后只得到用户一个。我想对结果做更多的聚合。
因此,例如:我希望为所有平均订单价格在范围内的用户重新分配存储桶 [0,10] 和 [10,20] 中 amout 字段的每个用户的平均值9-14.
我除了这个问题的答案是[0,10]桶中的0个和[10,20]桶中的一个(只保留用户1,因为他的平均价格。他的平均金额是11.5所以在存储桶 [10,20]) 中。
我试过的
我已经设法对我的过滤器进行操作,以检索平均订单价格在 9-14 范围内的用户。我通过首先对用户提交的术语聚合来做到这一点。然后我做一个子聚合,它是价格的平均聚合。然后我进行桶选择器管道聚合,检查先前计算的平均价格是否在 9 到 14 之间。
我也设法进行了我想要的聚合,但没有以前的过滤器。我为每个范围的过滤器做了完全相同的事情。然后我计算每个桶中的结果数。
我还没有找到任何方法来对存储桶选择器结果应用其他聚合。所以我不能先做过滤器然后再应用范围...
此外,这些解决方案也不优雅。我认为它们不会扩大,因为文档的很大一部分需要在答案中返回并进一步处理(即使它不在互联网上,我更愿意避免这样做我可能在聚合的结果大小方面受到限制?)。
我设法找到了解决方案,但它不够优雅,而且可扩展性可能很差。
- 对用户进行术语聚合。
- 作为术语聚合的子聚合,执行计算价格平均值的平均聚合。
作为术语聚合的子聚合,执行计算金额平均值的平均聚合。
执行桶选择器管道聚合,过滤以仅将 avg_price 保持在 [9-14] 范围内。
- 执行桶选择器管道聚合,过滤以仅将 avg_amount 保留在 [0-10] 中
- 执行 "count" 存储桶脚本管道聚合(脚本返回一个)。
- 对计数求和的桶总和管道聚合。
- 对所有想要的范围重复所有步骤([0-10]、[10-20])