如何使用Mongoose聚合查询关联订单表统计用户订单数并补充到查询结果
Mongoose 聚合实现方案
直接通过单次聚合管道调用即可实现需求,两种实现方式如下:
方式1:常规关联统计(适合数据量较小的场景)
const userOrderStats = await User.aggregate([ // 若仅需查询指定用户,放开下方$match阶段,填入对应用户ID即可 // { $match: { _id: 1 } }, // 关联订单集合,匹配用户ID与订单关联的用户ID { $lookup: { from: "orders", // 此处为MongoDB中Order集合的实际表名,默认是模型名小写加s,自定义表名请替换 localField: "_id", foreignField: "userId", as: "tempOrderList" } }, // 统计订单数组长度得到订单总量 { $addFields: { orderCount: { $size: "$tempOrderList" } } }, // 移除临时字段,返回符合要求的结构 { $project: { tempOrderList: 0 } } ])
方式2:预聚合关联(适合订单数据量大的场景,性能更优)
该方式在关联阶段就直接完成订单计数,不需要拉取全量订单数据到内存:
const userOrderStats = await User.aggregate([ // 若仅需查询指定用户,放开下方$match阶段,填入对应用户ID即可 // { $match: { _id: 1 } }, { $lookup: { from: "orders", let: { uid: "$_id" }, // 子管道直接对当前用户的订单做计数 pipeline: [ { $match: { $expr: { $eq: ["$userId", "$$uid"] } } }, { $count: "total" } ], as: "countTemp" } }, // 处理无订单用户的默认值为0 { $addFields: { orderCount: { $ifNull: [{ $first: "$countTemp.total" }, 0] } } }, // 移除临时字段 { $project: { countTemp: 0 } } ])
注意:请给Order集合的userId字段建立索引,可大幅提升关联查询的性能
内容的提问来源于stack exchange,提问作者Henry Okonkwo
相关产品推荐
相关产品推荐

