MongoDB订单统计问题:按日期汇总金额+按商品统计数量
MongoDB订单统计问题解决方案
一、按日期汇总订单总金额(覆盖指定区间所有日期,无订单日期补0)
问题原因
原查询统计全为0的核心问题有两个:
- 日期匹配逻辑错误:用
$dateFromParts生成的订单日期是当天0点UTC时间,但dateRange中的日期是带原始时分秒的时间(如2022-09-30T17:08:56.161Z),两者无法匹配,导致$cond判断始终为false。 - 字段映射错误:原代码将订单数和总金额的统计字段搞反,不符合预期结果的字段定义。
修正后的聚合查询
let endDate = new Date("2022-10-04T00:08:17.731Z"); let startDate = new Date("2022-09-25T00:08:56.161"); // 计算日期区间的总天数 const daysDiff = Math.ceil((endDate - startDate) / (1000 * 60 * 60 * 24)); const orderStats = await Order.aggregate([ // 1. 生成指定区间内的完整日期列表(保持和原dateRange一致的时分秒) { $documents: Array.from({ length: daysDiff }, (_, index) => { const currentDate = new Date(startDate); currentDate.setDate(startDate.getDate() + index); // 保留原始时间的时分秒,确保日期格式统一 return { date: new Date( currentDate.setHours( startDate.getHours(), startDate.getMinutes(), startDate.getSeconds(), startDate.getMilliseconds() ) ) }; }) }, // 2. 关联订单集合,统计对应日期的订单数据 { $lookup: { from: "orders", // 替换为你的订单集合实际名称 let: { targetDate: "$date" }, pipeline: [ { $match: { $expr: { $and: [ { $gte: ["$createdAt", startDate] }, { $lte: ["$createdAt", endDate] }, // 用$dateTrunc忽略时分秒,匹配同一天的订单 { $eq: [ { $dateTrunc: { date: "$createdAt", unit: "day" } }, { $dateTrunc: { date: "$$targetDate", unit: "day" } } ] } ] } } }, { $group: { _id: null, totalAmount: { $sum: "$total" }, // 统计当日订单总金额 orderCount: { $sum: 1 } // 统计当日订单数量 } } ], as: "dailyData" } }, // 3. 展开关联结果,无数据时保留空值 { $unwind: { path: "$dailyData", preserveNullAndEmptyArrays: true } }, // 4. 格式化输出,补全无订单日期的0值 { $project: { _id: 0, date: "$date", totalPrice: { $ifNull: ["$dailyData.totalAmount", 0] }, subtotal: { $ifNull: ["$dailyData.orderCount", 0] } } }, // 5. 按日期升序排序 { $sort: { date: 1 } } ]);
说明
- 先通过
$documents生成完整日期列表,确保覆盖指定区间的每一天。 - 用
$dateTrunc统一忽略时分秒,精准匹配同一天的订单。 - 借助
$lookup和preserveNullAndEmptyArrays实现左连接,自动为无订单日期补0。
二、按商品统计购买数量
聚合查询实现
const productPurchaseStats = await Order.aggregate([ // 可选:过滤有效订单(如排除已取消的订单) { $match: { status: { $nin: ["Cancelled"] } } }, // 展开购物车中的商品数组,将每个商品转为单独文档 { $unwind: "$cart.products" }, // 按商品ID分组,统计总购买数量 { $group: { _id: "$cart.products.product._id", totalQuantity: { $sum: "$cart.products.quantity" } } }, // 格式化输出字段 { $project: { _id: 0, productId: "$_id", totalQuantity: 1 } }, // 可选:按购买数量降序排序 { $sort: { totalQuantity: -1 } } ]);
说明
$unwind将每个订单中的商品数组拆分为独立文档,确保每个商品能单独统计。$group按商品ID聚合,累加每个商品的购买数量,得到总销量。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

