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

Elasticsearch 7.17.7按每3行分组求age平均值的方案咨询

Elasticsearch 7.17.7 分组求平均值解决方案

针对你提出的先按score升序排序,再每3行计算age平均值的需求,可以使用Elasticsearch的scripted_metric聚合来实现,以下是具体的查询DSL:

GET /your_index/_search
{
  "size": 0,
  "aggs": {
    "age_group_avg": {
      "scripted_metric": {
        "init_script": "state.docs = []",
        "map_script": "state.docs.add(['age': doc.age.value, 'score': doc.score.value])",
        "combine_script": """
          // 按score字段升序排序文档
          state.docs.sort((a, b) -> a.score.compareTo(b.score));
          def result = [];
          // 每3个文档为一组计算平均值
          for (int i = 0; i < state.docs.size(); i += 3) {
            def endIdx = Math.min(i + 3, state.docs.size());
            def group = state.docs.subList(i, endIdx);
            def ages = group.stream().mapToInt(doc -> doc.age).toArray();
            def sum = Arrays.stream(ages).sum();
            def avg = sum / ages.length;
            // 拼接成期望的格式字符串
            def expr = "(" + Arrays.stream(ages).mapToObj(String::valueOf).collect(Collectors.joining("+")) + ")/" + ages.length + " = " + avg;
            result.add(expr);
          }
          return result;
        """,
        "reduce_script": "return states.get(0);"
      }
    }
  }
}

关键部分说明

  1. size: 0:不返回原始文档,仅返回聚合结果,提升查询效率。
  2. scripted_metric聚合:
    • init_script:初始化一个空列表,用于存储每个文档的age和score数据。
    • map_script:遍历每个文档,将age和score以键值对形式加入列表。
    • combine_script:
      • 先对列表中的文档按score升序排序,匹配你的排序需求。
      • 循环将文档按每3个一组划分,计算每组年龄的总和与平均值,并拼接成你期望的格式字符串。
    • reduce_script:由于你使用单节点集群,直接取第一个分片的计算结果即可。

查询结果示例

执行上述查询后,返回的聚合结果会包含以下内容:

{
  ...
  "aggregations": {
    "age_group_avg": {
      "value": [
        "(15+17+22)/3 = 18",
        "(13+16+19)/3 = 16",
        "(17+15+25)/3 = 19"
      ]
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:10:34