MongoDB Java驱动聚合管道中按计算平均值排序的实现方向
问题描述
我正在使用MongoDB Java驱动执行聚合查询,按交易商分组计算平均交易发送金额。现有代码如下:
private static AggregateIterable<Document> averageVendorTotalSent(MongoCollection<Document> collection) { return collection.aggregate(Arrays.asList( Aggregates.group("$transaction vendor", Accumulators.avg("Average Vendor Transaction Sent", "$amount sent")) )); }
查询的文档结构示例:
{ "_id": "69cb3d75c6146e2646e66330", "date": "2026-02-17", "transaction vendor": "TIM HORTONS #47 _F", "amount sent": 11.21, "amount received": 0, "remainingBalance": 3269.39 }
当前查询能得到分组后的平均金额,但结果未排序,部分输出如下:
{"_id": "SQ *THE TASTE O _F", "Average Vendor Transaction Sent": 25.82} {"_id": "HECTOR'S YOUR I", "Average Vendor Transaction Sent": 27.72} {"_id": "TIM HORTONS #47 _F", "Average Vendor Transaction Sent": 10.573142857142857} {"_id": "SSV TO: 89966442264", "Average Vendor Transaction Sent": 2.75} {"_id": "7 ELEVEN STORE _F", "Average Vendor Transaction Sent": 14.66}
我希望按计算出的平均金额对结果排序,尝试过内置Sort函数但无法基于计算值排序,不想在Java端做排序(不够规范),想知道正确的实现方式和最佳实践。
解决方案
在聚合管道中添加$sort阶段即可实现基于计算字段的排序,聚合管道的阶段按顺序执行,在$group之后添加排序阶段就能对分组后的结果进行排序。
修改后的代码如下:
private static AggregateIterable<Document> averageVendorTotalSent(MongoCollection<Document> collection) { return collection.aggregate(Arrays.asList( // 按交易商分组计算平均发送金额 Aggregates.group("$transaction vendor", Accumulators.avg("Average Vendor Transaction Sent", "$amount sent")), // 按平均金额排序,1为升序,-1为降序 Aggregates.sort(Sorts.descending("Average Vendor Transaction Sent")) )); }
- 使用
Aggregates.sort()方法传入排序规则,Sorts.descending()表示降序排列,若需要升序则用Sorts.ascending() - 排序的字段名必须和
Accumulators.avg()中定义的键名完全一致(这里是Average Vendor Transaction Sent)
最佳实践
- 在数据库端完成排序:相比在Java客户端排序,数据库端排序能减少传输到客户端的数据量(尤其是数据量较大时),降低客户端的内存和CPU消耗
- 保持聚合逻辑的完整性:将排序纳入聚合管道,让整个数据处理逻辑都在数据库层完成,代码结构更清晰,也符合MongoDB聚合的设计理念
- 注意字段名一致性:排序阶段的字段名必须和分组阶段生成的计算字段名完全匹配,包括空格和大小写
内容的提问来源于stack exchange,提问作者Daniel anderson
相关产品推荐
相关产品推荐

