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

如何使用MongoDB聚合嵌套数组统计指定商品的月度销售额?

问题原因及修复方案

1. 直接导致查询不生效的错误:$elemMatch匹配规则写法错误

你当前的$elemMatch: { product: { _id: productId } }写法是要求数组项的product字段完全等于{_id: productId}这个对象,必须完全匹配所有字段才会命中,而不是仅匹配product下的_id字段,因此永远查不到符合条件的订单。
正确的嵌套字段匹配写法应该使用点语法:

products: { $elemMatch: { "product._id": productId } }

2. 隐藏逻辑问题:现有统计逻辑不符合单商品销售额统计要求

就算修正了匹配规则,你当前的聚合逻辑统计的是「包含指定商品的订单总金额」,如果订单同时包含其他商品,统计结果会包含其他商品的销售额,不是指定商品本身的月度销售额。
如果需要统计指定商品的准确销售额,需要调整聚合流程:先展开商品数组、单独匹配目标商品项、再按商品的单价*购买数量累加统计。


修正后的完整代码

public async getIncome(productId?: string) {
    const date = new Date();
    const lastMonth = new Date(date.setMonth(date.getMonth() - 1));
    const income = await this.order.aggregate([
      {
        $match: {
          createdAt: { $gte: lastMonth },
          // 先过滤包含目标商品的订单,减少后续计算量
          ...(productId && {
            products: { $elemMatch: { "product._id": productId } },
          }),
        },
      },
      // 展开商品数组,把每个商品拆为单独文档
      { $unwind: "$products" },
      // 单独匹配目标商品项
      ...(productId ? [{
        $match: { "products.product._id": productId }
      }] : []),
      {
        $project: {
          month: { $month: '$createdAt' },
          // 计算单条商品的销售额:单价 * 购买数量
          singleSale: { $multiply: ["$products.product.price", "$products.quantity"] }
        },
      },
      {
        $group: {
          _id: '$month',
          total: { $sum: '$singleSale' },
        },
      },
    ]);
    return income;
  }

补充注意项

  • 确认传入的productId类型和Schema中product._id的类型一致,两者都为String类型,不要传入ObjectId实例,否则类型不匹配也会查询失败。
  • 你代码中声明的previousMonth变量未被使用,如果要统计上上个月到当前的销售额,替换$match中时间判断的边界值即可。

内容的提问来源于stack exchange,提问作者Kai021195

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:24:02