聚合结果的 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])