如何在MongoDB中对文档内对象数组的指定字段进行排序
MongoDB 数组内字段排序实现方案
你之前的写法不生效的核心原因是lot_items是对象数组类型,直接指定lot_items.buy时MongoDB无法确认要使用数组中哪一个元素的buy值参与排序,因此规则不会生效。根据你的实际需求可以选择以下两种实现方案:
方案1:对单个lot文档内的lot_items数组元素排序(适用于MongoDB 5.2及以上版本)
如果你只需要调整每个lot下lot_items数组内部的元素顺序,直接使用$sortArray操作符即可,在聚合管道中新增如下阶段:
{ $addFields: { "lot_items": { $sortArray: { input: "$lot_items", sortBy: { "origin_port.port_name": 1, // 1为升序,-1为降序,可自行调整 "destination_port.port_name": 1, "buy": 1, "sell": -1, "allowable_weight": 1 } } } } }
方案2:对整个lot文档列表排序/低版本MongoDB兼容方案
如果你需要根据lot_items内字段的值对整个lot文档排序,或者使用的MongoDB版本低于5.2,可以通过「展开数组-排序-重组数组」的流程实现,聚合管道按顺序添加以下三个阶段:
- 展开lot_items数组
{ $unwind: "$lot_items" }
- 按指定字段排序
{ $sort: { "lot_items.origin_port.port_name": 1, "lot_items.destination_port.port_name": 1, "lot_items.buy": 1, "lot_items.sell": -1, "lot_items.allowable_weight": 1 } }
- 重组lot_items数组(如果不需要保留原数组结构可以省略此阶段)
{ $group: { _id: "$_id", lot_no: { $first: "$lot_no" }, location: { $first: "$location" }, shipping_line_id: { $first: "$shipping_line_id" }, shipping_line_name: { $first: "$shipping_line_name" }, containers: { $first: "$containers" }, status: { $first: "$status" }, lot_items: { $push: "$lot_items" } } }
注意事项
- 排序规则中的
1代表升序,-1代表降序,你可以根据需求调整每个字段的排序方向 - 如果单个lot下存在多个lot_items元素,
$unwind后会为每个元素生成独立的行,$group阶段使用$first保留原lot的其他字段即可
内容的提问来源于stack exchange,提问作者Anuj Panchal
相关产品推荐
相关产品推荐

