MongoDB:基于数组字段排序集合文档及数组元素的实现问题
MongoDB 同时排序集合文档与内部数组元素
我的集合中有以下文档:
[ { "name": "sam", "age": 20, "hobbies": [ { "id": 1, "value": "football" }, { "id": 2, "value": "chess" } ] }, { "name": "Bob", "age": 30, "hobbies": [ { "id": 1, "value": "painting" }, { "id": 2, "value": "gardening" } ] }, { "name": "Charlie", "age": 22, "hobbies": [ { "id": 1, "value": "cycling" }, { "id": 2, "value": "playing the guitar" }, { "id": 3, "value": "photography" } ] } ]
我尝试用{ $sort: { "hobbies.value": 1 } }做排序,但发现这个操作只把每个文档里的hobbies数组元素排了序,集合里的文档本身并没有按要求排序。我需要同时完成两件事:
- 把每个文档内的hobbies数组按
value字段升序排列 - 把整个集合的文档,基于hobbies数组的
value字段升序排序
预期的正确结果是:
[ { "name": "sam", "age": 20, "hobbies": [ { "id": 2, "value": "chess" }, { "id": 1, "value": "football" } ] }, { "name": "Charlie", "age": 22, "hobbies": [ { "id": 1, "value": "cycling" }, { "id": 2, "value": "playing the guitar" }, { "id": 3, "value": "photography" } ] }, { "name": "Bob", "age": 30, "hobbies": [ { "id": 2, "value": "gardening" }, { "id": 1, "value": "painting" } ] } ]
解决方案
要同时实现这两个排序需求,得用MongoDB的聚合管道分两步处理:
方法1(MongoDB 5.0+ 推荐)
利用$sortArray直接排序数组,再基于数组首元素排序文档:
db.collection.aggregate([ // 先给每个文档的hobbies数组按value升序排序 { $addFields: { hobbies: { $sortArray: { input: "$hobbies", sortBy: { value: 1 } } } } }, // 再用排序后hobbies数组的第一个value值,对整个集合的文档升序排序 { $sort: { "hobbies.0.value": 1 } } ])
方法2(兼容低版本MongoDB)
如果你的MongoDB版本低于5.0,用$unwind+$sort+$group的组合来实现数组排序:
db.collection.aggregate([ // 拆分hobbies数组成独立文档 { $unwind: "$hobbies" }, // 按hobbies.value升序排序拆分后的元素 { $sort: { "hobbies.value": 1 } }, // 重新将元素组合回原文档的hobbies数组 { $group: { _id: "$_id", name: { $first: "$name" }, age: { $first: "$age" }, hobbies: { $push: "$hobbies" } } }, // 最后按排序后hobbies数组的第一个value值,对文档升序排序 { $sort: { "hobbies.0.value": 1 } } ])
内容的提问来源于stack exchange,提问作者SAMRAT
相关产品推荐
相关产品推荐

