Quarkus Panache集成MongoDB:如何使用aggregate方法?
解决方案
要将你提供的MongoDB聚合查询转换为Quarkus Panache兼容的List<? extends Bson>格式,需要使用Mongo Java驱动4.x+的新API(Quarkus Panache MongoDB默认集成该版本),替代旧的DBObject类。以下是修正后的实现:
完整代码示例
import org.bson.Document; import org.bson.types.ObjectId; import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Accumulators; import io.smallrye.mutiny.Uni; import java.util.List; // 假设Rating是你的实体类,继承自PanacheMongoEntity或使用PanacheMongoRepository public class RatingRepository { public Uni<Double> getAverage(String productId) { // 构建$match阶段:匹配指定productId的文档 Bson matchStage = Aggregates.match(new Document("productId", new ObjectId(productId))); // 构建$group阶段:按productId分组,计算score字段的平均值 Bson groupStage = Aggregates.group("$productId", Accumulators.avg("Average", "$score")); // 执行聚合查询并返回结果 return Rating.mongoCollection() .aggregate(List.of(matchStage, groupStage)) .first() // 分组后仅会返回一条结果 .map(aggregateResult -> aggregateResult.getDouble("Average")); } }
关键修正点说明
- 替换旧API:放弃使用
DBObject,改用Bson接口的实现类(如Document)或Aggregates工具类构建聚合阶段,这是新Mongo驱动的标准用法,符合aggregate方法的参数要求。 - 补全聚合逻辑:你之前的代码缺少
$group阶段中的$avg累加器,需要通过Accumulators.avg()来定义平均值计算规则。 - 修正返回类型:
$avg操作返回的是浮点数,因此将返回类型从Integer改为Double更合理。 - 结果映射:通过
first()获取唯一的分组结果,再通过map()提取出平均值字段。
替代实现(手动构造Document)
如果你更习惯手动构造聚合文档,也可以用以下方式:
public Uni<Double> getAverage(String productId) { Bson matchStage = new Document("$match", new Document("productId", new ObjectId(productId))); Bson groupStage = new Document("$group", new Document("_id", "$productId") .append("Average", new Document("$avg", "$score"))); return Rating.mongoCollection() .aggregate(List.of(matchStage, groupStage)) .first() .map(result -> result.getDouble("Average")); }
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

