【问题标题】:Elasticsearch Aggregations: Only return results of one of them?Elasticsearch Aggregations:只返回其中之一的结果?
【发布时间】:2019-05-04 18:44:20
【问题描述】:

我正在尝试找到一种仅在 Elasticsearch 查询中返回一个聚合结果的方法。我有一个最大桶聚合(我希望看到的那个),它是从基于日期直方图聚合的总桶聚合计算出来的。现在,我必须查看 1,440 个结果才能找到我想看到的结果。我已经使用 size: 0 修饰符删除了基本查询的结果,但是有没有办法对聚合做类似的事情?我试过把同样的东西滑到几个地方,但没有运气。

这是查询:

{
    "size": 0,
    "query": {
        "range": {
            "timestamp": {
                "gte": "2018-11-28",
                "lte": "2018-11-28"
            }
        }
    },
    "aggs": {
        "hits_per_minute": {
            "date_histogram": {
                "field": "timestamp",
                "interval": "minute"
            },
            "aggs": {
                "total_hits": {
                    "sum": {
                        "field": "hits_count"
                    }
                }
            }
        },
        "max_transactions_per_minute": {
            "max_bucket": {
                "buckets_path": "hits_per_minute>total_hits"
            }
        }
    }
}

【问题讨论】:

  • 请问您使用的是哪个版本的 Elasticsearch?从这个问题中不清楚你真正想看到的那些 1440 中的哪个桶,你能澄清一下吗?如果您发布了几个示例文档和所需的输出,将会有所帮助。谢谢。
  • 6.4.3。 1440是指一天的分钟数;上面的查询按分钟在日期直方图中生成一组总和指标,最大存储桶聚合基于这些指标生成单个指标。无论我在查询正文中列出存储桶的顺序如何,它总是将最大存储桶放在响应正文的最后。文档内容无关紧要。
  • 如果您不想要hits_per_minute agg,那么只需将其删除即可。它不会影响 max_transactions_per_minute 聚合,因为两者是相互独立的。

标签: elasticsearch elasticsearch-aggregation


【解决方案1】:

幸运的是,您可以使用 Elasticsearch 6.4 中添加的 bucket_sort aggregation 来做到这一点。

使用bucket_sort

POST my_index/doc/_search
{
  "size": 0,
  "query": {
    "range": {
      "timestamp": {
        "gte": "2018-11-28",
        "lte": "2018-11-28"
      }
    }
  },
  "aggs": {
    "hits_per_minute": {
      "date_histogram": {
        "field": "timestamp",
        "interval": "minute"
      },
      "aggs": {
        "total_hits": {
          "sum": {
            "field": "hits_count"
          }
        },
        "max_transactions_per_minute": {
          "bucket_sort": {
            "sort": [
              {"total_hits": {"order": "desc"}}
            ],
            "size": 1
          }
        }
      }
    }
  }
}

这会给你这样的回应:

{
  ...
  "aggregations": {
    "hits_per_minute": {
      "buckets": [
        {
          "key_as_string": "2018-11-28T21:10:00.000Z",
          "key": 1543957800000,
          "doc_count": 3,
          "total_hits": {
            "value": 11
          }
        }
      ]
    }
  }
}

请注意,输出中没有额外的聚合,hits_per_minute 的输出被截断(因为我们要求只给出一个最顶层的存储桶)。

使用filter_path

还有一种过滤 Elasticsearch 输出的通用方法:Response filtering,正如 this answer 所建议的那样。

在这种情况下,只需执行以下查询就足够了:

POST my_index/doc/_search?filter_path=aggregations.max_transactions_per_minute
{ ... (original query) ... }

这将给出响应:

{
  "aggregations": {
    "max_transactions_per_minute": {
      "value": 11,
      "keys": [
        "2018-12-04T21:10:00.000Z"
      ]
    }
  }
}

【讨论】:

  • filter_path 选项非常适合我。谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-11-19
  • 2021-04-19
  • 2014-06-06
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多