Elasticsearch嵌套聚合问题:如何获取每个磁盘每日的最大负载值
Elasticsearch嵌套聚合问题:如何获取每个磁盘每日的最大负载值
你遇到的这个问题我太熟悉了!核心原因是Elasticsearch默认会把数组字段做扁平化处理——你直接对points.name和points.load做聚合时,ES不会把同一个数组元素里的name和load绑定在一起,而是把所有磁盘的名称、所有负载值当成两个独立的集合来计算,所以才会出现D盘的最大负载也取到了C盘的83,完全乱了对应关系。
要解决这个问题,咱们得用nested聚合来告诉ES:把points数组里的每个元素当成独立的小文档来处理,这样每个磁盘的名称和负载值就能一一对应上了。
下面是修正后的完整查询:
{ "size": 0, "query": { "bool": { "must": [ { "range": { "timestamp": { "gte": "now-29d/d", "lte": "now/d" } } }, { "term": { "resourceId.keyword": { "value": "e5735563-2b4c-46e9-a38d-4728a5617ebc" } } }, { "term": { "tenantId.keyword": { "value": "d7842881-31c9-4974-bc87-7a621ba440a5" } } }, { "bool": { "should": [ { "term": { "points.measurement.keyword": { "value": "win_logical_disk" } } }, { "term": { "points.measurement.keyword": { "value": "lnx_logical_disk" } } }, { "term": { "points.measurement.keyword": { "value": "ibmi_asp" } } } ] } } ] } }, "aggs": { "date_histogram": { "date_histogram": { "field": "timestamp", "calendar_interval": "day", "extended_bounds": { "min": "now-29d/d", "max": "now/d" } }, "aggs": { "nested_points": { "nested": { "path": "points" }, "aggs": { "disk": { "terms": { "field": "points.name.keyword" }, "aggs": { "max_load": { "max": { "field": "points.load" } } } } } } } } } }
咱们来拆解一下关键改动:
- 在日期直方图聚合内部,新增了
nested_points这个nested聚合,指定路径为points——这一步是核心,让ES把数组里的每个磁盘数据当成独立个体处理。 - 后续的磁盘名称分组、最大负载计算,都放在这个
nested聚合内部,这样就能保证每个磁盘的name和load是对应的。
另外要注意:如果你的points字段在索引的映射里还不是nested类型,这个查询可能不会生效,需要先把字段映射改成nested类型(如果是新建索引可以直接设置,已有数据的话需要重新索引)。
用你提供的那单条文档测试这个查询,就能得到你想要的结果:C盘最大负载83,D盘最大负载44啦!
备注:内容来源于stack exchange,提问作者KLassiux
相关产品推荐
相关产品推荐

