MongoDB按ID查询并对history数组按updateDate排序取前2项问题
MongoDB查询:按ID获取文档并处理嵌套数组
需求:通过文档ID查询MongoDB文档,将文档内的history数组按updateDate字段排序,仅保留数组的前2项。
示例文档结构:
{ "_id" : ObjectId("63b5c0f016c75b6c2e36575f"), "history" : [ { "adress" : [ "KKK" ], "updateDate" : ISODate("2023-01-04T15:09:52.121-03:00") }, { "adress" : [ "YYY" ], "updateDate" : ISODate("2023-01-04T15:10:03.303-03:00") }, { "adress" : [ "ZZZ" ], "updateDate" : ISODate("2023-01-04T15:12:08.160-03:00") } ] }
你尝试的查询代码(未达到预期效果):
db.collection.find( {_id: ObjectId("63b5c0f016c75b6c2e36575f")}, {"history":{$slice: -2}} ) .sort({"history.updateDate": -1})
问题原因
find()后的.sort()是对文档集合进行排序,而非对文档内部的数组元素排序。$slice仅截取数组固定位置的元素,不会先对数组做排序处理。
正确解决方案
使用聚合管道实现数组内部排序与截取:
db.collection.aggregate([ // 匹配目标文档 { $match: { _id: ObjectId("63b5c0f016c75b6c2e36575f") } }, // 对history数组按updateDate降序排序 { $addFields: { history: { $sortArray: { input: "$history", sortBy: { updateDate: -1 } // -1为降序,1为升序 } } } }, // 截取排序后的数组前2项 { $project: { history: { $slice: ["$history", 2] } } } ])
兼容旧版MongoDB(无$sortArray版本)
若你的MongoDB版本低于5.2(不支持$sortArray),可使用以下替代方案:
db.collection.aggregate([ { $match: { _id: ObjectId("63b5c0f016c75b6c2e36575f") } }, // 拆解数组元素 { $unwind: "$history" }, // 按updateDate降序排序数组元素 { $sort: { "history.updateDate": -1 } }, // 重新组合数组并保留前2项 { $group: { _id: "$_id", history: { $push: "$history" } } }, { $project: { history: { $slice: ["$history", 2] } } } ])
内容的提问来源于stack exchange,提问作者Jerrold
相关产品推荐
相关产品推荐

