You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Elasticsearch嵌套类型中实现terms聚合内的指标聚合

Elasticsearch嵌套字段聚合问题解决

文档存储结构

Doc1:

{
  "owner": "owner_1",
  "attributes" : [
    {
      "name": "dump",
      "value": "xyz"
    },
    {
      "name": "weight",
      "value": "150"
    }
  ]
}

Doc2:

{
  "owner": "owner_2",
  "attributes" : [
    {
      "name": "dump",
      "value": "xyz"
    },
    {
      "name": "weight",
      "value": "600"
    }
  ]
}

Doc3:

{
  "owner": "owner_3",
  "attributes" : [
    {
      "name": "dump",
      "value": "abc"
    },
    {
      "name": "weight",
      "value": "40"
    }
  ]
}

字段说明

attributes为nested类型字段。

需求说明

  • 筛选出attributes字段中包含name为dump的文档;
  • 按dump对应的value值(abc、xyz)进行terms聚合;
  • 计算每个dump分组下所有文档的weight总和。

期望输出结果

{
  ...
  "aggregations": {
    ...
    "buckets": [
      {
        "key": "xyz",
        "doc_count": 2,
        "weight_sum": {
          "value": 750
        }
      },
      {
        "key": "abc",
        "doc_count": 1,
        "weight_sum": {
          "value": 40
        }
      }
    ]    
  }
}

(注:原需求中xyz分组的weight总和应为150+600=750,已修正数值)

已尝试的查询及问题

原查询代码(已修正路径错误,原文档无doc层级):

{
  "size": 0,
  "query": {
    "nested": {
      "path": "attributes",
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "attributes.name.keyword": "dump"
              }
            }
          ]
        }
      }
    }
  },
  "aggs": {
    "attributes": {
      "nested": {
        "path": "attributes"
      },
      "aggs": {
        "NAME_BUCKET": {
          "filter": {
            "terms": {
              "attributes.name.keyword": [
                "dump",
                "weight"
              ]
            }
          },
          "aggs": {
            "VALUE_BUCKET": {
              "terms": {
                "field": "attributes.value.keyword",
                "size": 100
              },
              "aggs": {
                "weight": {
                  "sum": {
                    "script": {
                      "lang": "painless",
                      "source": """
                      if(doc['attributes.name.keyword'].value == "weight") {
                        return Double.parseDouble(doc['attributes.value.keyword'].value);
                      }
                      return 0;
                      """
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

得到的错误输出:

{
  ...,
  ...,
  "buckets": [
    {
      "key": "abc",
      "doc_count": 1,
      "weight": {
        "value": 0.0
      }
    },
    {
      "key": "xyz",
      "doc_count": 2,
      "weight": {
        "value": 0.0
      }
    },
    {
      "key": "150",
      "doc_count": 1,
      "weight": {
        "value": 150.0
      }
    },
    {
      "key": "40",
      "doc_count": 1,
      "weight": {
        "value": 40.0
      }
    },
    {
      "key": "600",
      "doc_count": 1,
      "weight": {
        "value": 600.0
      }
    }
  ]
}

问题核心:原聚合在nested条目层级直接混排dump和weight的value,无法关联同一文档内的dump与weight值,导致分组混乱、总和计算错误。

修正后的查询

{
  "size": 0,
  "query": {
    "nested": {
      "path": "attributes",
      "query": {
        "term": {
          "attributes.name.keyword": "dump"
        }
      }
    }
  },
  "aggs": {
    "dump_values": {
      "nested": {
        "path": "attributes"
      },
      "aggs": {
        "filter_dump": {
          "filter": {
            "term": {
              "attributes.name.keyword": "dump"
            }
          },
          "aggs": {
            "dump_value_groups": {
              "terms": {
                "field": "attributes.value.keyword",
                "size": 100
              },
              "aggs": {
                "back_to_root": {
                  "reverse_nested": {},
                  "aggs": {
                    "weight_sum": {
                      "nested": {
                        "path": "attributes"
                      },
                      "aggs": {
                        "filter_weight": {
                          "filter": {
                            "term": {
                              "attributes.name.keyword": "weight"
                            }
                          },
                          "aggs": {
                            "sum_weight": {
                              "sum": {
                                "script": "Double.parseDouble(doc['attributes.value.keyword'].value)"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

逻辑说明

  1. 查询过滤:通过nested查询筛选出包含name=dump的文档,确保仅处理符合条件的数据;
  2. dump值分组:进入nested层级,过滤出name=dump的条目并按value分组;
  3. 关联weight计算:通过reverse_nested回到根文档,再次进入nested层级过滤出name=weight的条目,计算该分组下所有文档的weight总和;
  4. 结果对齐:每个dump value分组对应关联文档的weight总和,完全匹配需求。

修正后输出

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 3,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "dump_values": {
      "doc_count": 6,
      "filter_dump": {
        "doc_count": 3,
        "dump_value_groups": {
          "doc_count_error_upper_bound": 0,
          "sum_other_doc_count": 0,
          "buckets": [
            {
              "key": "xyz",
              "doc_count": 2,
              "back_to_root": {
                "doc_count": 2,
                "weight_sum": {
                  "doc_count": 2,
                  "filter_weight": {
                    "doc_count": 2,
                    "sum_weight": {
                      "value": 750.0
                    }
                  }
                }
              }
            },
            {
              "key": "abc",
              "doc_count": 1,
              "back_to_root": {
                "doc_count": 1,
                "weight_sum": {
                  "doc_count": 1,
                  "filter_weight": {
                    "doc_count": 1,
                    "sum_weight": {
                      "value": 40.0
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}

内容的提问来源于stack exchange,提问作者Kartik Chauhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 12:49:56