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

MongoDB跨集合计算总销售额:Outlet-A及2018年营收查询需求

没问题,这两个跨集合计算营收的需求,用MongoDB的聚合框架结合$lookup就能轻松搞定!先假设你的集合结构大概是这样(如果实际字段有出入,调整匹配条件即可):

  • sales集合字段示例:_id, productId(关联products的_id), outlet(门店名称), saleDate(销售日期,Date类型), quantity(销售数量)
  • products集合字段示例:_id, price(产品单价)

1. 计算Outlet-A产生的总营收

这个查询会先筛选出门店为Outlet-A的销售记录,关联对应产品的价格,计算每条记录的营收(数量×单价)后求和:

db.sales.aggregate([
  // 第一步:筛选Outlet-A的销售记录
  { $match: { outlet: "Outlet-A" } },
  // 第二步:关联products集合,匹配产品ID
  {
    $lookup: {
      from: "products",
      localField: "productId",
      foreignField: "_id",
      as: "productInfo"
    }
  },
  // 第三步:展开关联的产品信息数组($lookup默认返回数组)
  { $unwind: { path: "$productInfo", preserveNullAndEmptyArrays: true } },
  // 第四步:计算单条销售的营收,兼容无匹配产品的情况(设为0)
  {
    $addFields: {
      revenue: {
        $multiply: [
          "$quantity",
          { $ifNull: ["$productInfo.price", 0] }
        ]
      }
    }
  },
  // 第五步:求和所有营收
  {
    $group: {
      _id: null,
      totalRevenueOutletA: { $sum: "$revenue" }
    }
  },
  // 可选:重命名字段让输出更直观
  {
    $project: {
      _id: 0,
      "Outlet-A总营收": "$totalRevenueOutletA"
    }
  }
])

2. 计算2018年产生的总营收

这个查询先筛选2018年的销售记录,同样关联产品价格后求和:

db.sales.aggregate([
  // 第一步:筛选2018年的销售记录(针对Date类型的saleDate)
  {
    $match: {
      saleDate: {
        $gte: ISODate("2018-01-01T00:00:00Z"),
        $lt: ISODate("2019-01-01T00:00:00Z")
      }
    }
  },
  // 第二步:关联products集合
  {
    $lookup: {
      from: "products",
      localField: "productId",
      foreignField: "_id",
      as: "productInfo"
    }
  },
  // 第三步:展开关联数组
  { $unwind: { path: "$productInfo", preserveNullAndEmptyArrays: true } },
  // 第四步:计算单条营收
  {
    $addFields: {
      revenue: {
        $multiply: [
          "$quantity",
          { $ifNull: ["$productInfo.price", 0] }
        ]
      }
    }
  },
  // 第五步:求和所有营收
  {
    $group: {
      _id: null,
      totalRevenue2018: { $sum: "$revenue" }
    }
  },
  // 可选:重命名字段
  {
    $project: {
      _id: 0,
      "2018年总营收": "$totalRevenue2018"
    }
  }
])

优化补充:一次性计算两个结果

如果想同时得到两个总营收,用$facet可以只做一次跨集合关联,效率更高:

db.sales.aggregate([
  {
    $lookup: {
      from: "products",
      localField: "productId",
      foreignField: "_id",
      as: "productInfo"
    }
  },
  { $unwind: { path: "$productInfo", preserveNullAndEmptyArrays: true } },
  {
    $addFields: {
      revenue: {
        $multiply: [
          "$quantity",
          { $ifNull: ["$productInfo.price", 0] }
        ]
      },
      isOutletA: { $eq: ["$outlet", "Outlet-A"] },
      is2018: {
        $and: [
          { $gte: ["$saleDate", ISODate("2018-01-01T00:00:00Z")] },
          { $lt: ["$saleDate", ISODate("2019-01-01T00:00:00Z")] }
        ]
      }
    }
  },
  {
    $facet: {
      outletARevenue: [
        { $match: { isOutletA: true } },
        { $group: { _id: null, total: { $sum: "$revenue" } } },
        { $project: { _id: 0, "Outlet-A总营收": "$total" } }
      ],
      year2018Revenue: [
        { $match: { is2018: true } },
        { $group: { _id: null, total: { $sum: "$revenue" } } },
        { $project: { _id: 0, "2018年总营收": "$total" } }
      ]
    }
  }
])

注意:如果你的saleDate是字符串类型,需要先通过$toDate转换为Date类型再筛选;如果确定所有销售记录都有对应产品,可以去掉preserveNullAndEmptyArrays: true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:13:51