如何在Mongoose中根据createdAt对数组内的对象排序?
解决MongoDB订单内products数组按createdAt排序的问题
你当前用的sort({ 'products.createdAt': -1 })是用来对订单文档进行排序的,不是对订单内部的products数组元素排序,所以不会改变数组里元素的顺序。下面给两种可行的解决方法:
方法一:数据库层面用聚合管道排序(适合大数据量)
利用MongoDB的聚合管道直接在数据库里完成数组排序、截取和关联操作,效率更高:
const orders = await Order.aggregate([ // 匹配当前用户的订单 { $match: { userId: req.userId } }, // 对products数组按createdAt降序排序 { $addFields: { products: { $sortArray: { input: "$products", sortBy: { createdAt: -1 } } } } }, // 截取前10个products元素 { $addFields: { products: { $slice: ["$products", 10] } } }, // 关联Product集合的信息 { $lookup: { from: "products", // 这里要填Product模型对应的集合名称,一般是小写复数形式 localField: "products.productId", foreignField: "_id", as: "populatedProducts" } }, // 将关联后的产品信息合并到products数组中 { $addFields: { products: { $map: { input: "$products", as: "item", in: { $mergeObjects: [ "$$item", { productId: { $arrayElemAt: [ "$populatedProducts", { $indexOfArray: [ "$populatedProducts._id", "$$item.productId" ] } ] } } ] } } } } }, // 移除临时字段 { $project: { populatedProducts: 0 } } ]); // 聚合返回的是数组,取第一个订单文档 const targetOrder = orders[0];
方法二:获取数据后用JavaScript排序(适合小数据量)
如果订单内的products数量不多,可以直接在拿到文档后用JS的sort方法处理,写法更简单:
let targetOrder = await Order.findOne({ userId: req.userId }) .populate({ path: 'products.productId', select: 'images title' }); // 按createdAt降序排序数组 targetOrder.products.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()); // 截取前10个元素 targetOrder.products = targetOrder.products.slice(0, 10);
内容的提问来源于stack exchange,提问作者Kaushal
相关产品推荐
相关产品推荐

