You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:42:10