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

Spring项目中MongoDB聚合avg查询转Java代码问题

解决Spring Data MongoDB中ProjectionOperation使用$avg的问题

我明白你遇到的困扰了——Spring Data MongoDB的ProjectionOperation确实没有直接提供avg()方法,但这不代表我们不能在投影阶段使用$avg聚合函数,只需要换一种方式手动构建表达式就行。

先看你的原MongoDB查询:

db.test.aggregate([
  {$unwind: "$reports"}, 
  {$project: {reports: 1, avg: {$avg: "$reports.linesCount"}}}
])

不过这里有个小细节:unwind之后每个文档只包含单个reports对象,所以$avg计算的其实就是当前文档的linesCount值。如果你的真实需求是计算每个原始文档下所有reports.linesCount的平均值,其实不需要unwind,直接在投影阶段对数组字段用$avg即可;如果确实需要unwind后再计算,下面的代码都能覆盖。

解决方案1:使用andExpression()快速构建投影

这是最简洁的方式,直接通过字符串表达式来定义$avg操作:

import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation;
import org.springframework.data.mongodb.core.aggregation.UnwindOperation;

// 构建unwind操作(如果不需要可以去掉)
UnwindOperation unwind = Aggregation.unwind("$reports");

// 构建投影操作,手动添加$avg表达式
ProjectionOperation project = Aggregation.project("reports")
    .andExpression("avg(reports.linesCount)") // 直接用表达式语法
    .as("avg"); // 指定输出字段名

// 组合聚合操作
Aggregation aggregation = Aggregation.newAggregation(unwind, project);

解决方案2:使用AggregationExpression自定义表达式

如果需要更灵活的控制(比如复杂的条件聚合),可以用AggregationExpression手动构建MongoDB的$avg文档:

import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationExpression;
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation;
import org.springframework.data.mongodb.core.aggregation.UnwindOperation;
import org.bson.Document;

UnwindOperation unwind = Aggregation.unwind("$reports");

// 自定义$avg表达式
AggregationExpression avgExpr = context -> new Document("$avg", "$reports.linesCount");

ProjectionOperation project = Aggregation.project("reports")
    .and(avgExpr)
    .as("avg");

Aggregation aggregation = Aggregation.newAggregation(unwind, project);

补充:如果需求是计算全局平均值

如果你想要的是所有unwind后文档的linesCount的全局平均值,那需要用GroupOperation来实现(这也是你之前注意到的Group支持avg的场景):

import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.GroupOperation;
import org.springframework.data.mongodb.core.aggregation.UnwindOperation;

UnwindOperation unwind = Aggregation.unwind("$reports");

// 按null分组(全局分组),计算平均值
GroupOperation group = Aggregation.group()
    .avg("reports.linesCount")
    .as("avg");

Aggregation aggregation = Aggregation.newAggregation(unwind, group);

这样就能完美匹配你想要的聚合逻辑啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:10:21