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

MongoDB统计未换货订单占比:如何同时获取总文档数?

嘿,我来帮你搞定这个MongoDB统计需求!你已经知道怎么查无换货的订单数了,现在只需要把总订单数的统计和它整合到一次聚合查询里就行,这样既高效又能直接计算出你要的比例。

首先,我注意到你写的计算公式和“未换货订单占比”的描述有点矛盾——通常占比是「无换货订单数/总订单数×100」,但你给出的公式是「(换货订单数×100)/无换货订单数」。我会在下面的查询里同时包含这两种计算,你可以根据实际需求选用。

方法一:用$facet并行统计(推荐)

$facet是MongoDB聚合里的神器,它能让你在一次查询里运行多个独立的聚合管道,刚好可以同时拿到无换货订单数和总订单数:

db.orders.aggregate([
  {
    $facet: {
      // 统计无换货的订单数(就是你原来的查询)
      noExchangeOrders: [
        { $match: { exchange_order_products: { $exists: true, $size: 0 } } },
        { $count: 'count' }
      ],
      // 统计总订单数
      totalOrders: [
        { $count: 'count' }
      ]
    }
  },
  {
    $project: {
      // 把数组里的数值提取出来(因为$count返回的是单元素数组)
      noExchangeCount: { $arrayElemAt: ['$noExchangeOrders.count', 0] },
      totalCount: { $arrayElemAt: ['$totalOrders.count', 0] },
      // 计算有换货的订单数
      exchangeCount: { $subtract: ['$totalCount', '$noExchangeCount'] },
      // 按你给出的公式计算:(换货订单数 × 100) / 无换货订单数
      exchangeToNoExchangeRatio: {
        $cond: {
          if: { $eq: ['$noExchangeCount', 0] },
          then: null, // 避免除以0的错误
          else: { $multiply: [{ $divide: ['$exchangeCount', '$noExchangeCount'] }, 100] }
        }
      },
      // 正确的未换货订单占比:(无换货订单数 × 100) / 总订单数
      noExchangePercentage: {
        $multiply: [{ $divide: ['$noExchangeCount', '$totalCount'] }, 100]
      }
    }
  }
])

方法二:用$group一次性统计

如果你更喜欢用$group来做汇总,也可以这样写:

db.orders.aggregate([
  {
    $group: {
      _id: null, // 按null分组,把所有文档归为一组
      totalOrders: { $sum: 1 }, // 统计总订单数,每一条文档加1
      noExchangeOrders: {
        // 判断当前订单是否是无换货订单,符合条件就加1
        $sum: {
          $cond: {
            if: { $and: [{ $exists: ['$exchange_order_products', true] }, { $eq: [{ $size: '$exchange_order_products' }, 0] }] },
            then: 1,
            else: 0
          }
        }
      }
    }
  },
  {
    $project: {
      _id: 0, // 隐藏_id字段
      noExchangeOrders: 1,
      totalOrders: 1,
      exchangeOrders: { $subtract: ['$totalOrders', '$noExchangeOrders'] },
      // 按你的公式计算比例
      exchangeToNoExchangeRatio: {
        $cond: {
          if: { $eq: ['$noExchangeOrders', 0] },
          then: null,
          else: { $multiply: [{ $divide: ['$exchangeOrders', '$noExchangeOrders'] }, 100] }
        }
      },
      // 未换货订单占比
      noExchangePercentage: { $multiply: [{ $divide: ['$noExchangeOrders', '$totalOrders'] }, 100] }
    }
  }
])

小提醒

如果你的集合里存在没有exchange_order_products字段的订单,而你想把这些订单也归为“未换货”类别,那需要调整判断条件:

  • 比如在$match里改成:{ $or: [{ exchange_order_products: { $exists: false } }, { exchange_order_products: { $size: 0 } }] }
  • 或者在$cond的判断里加入$exists: false的情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 11:42:37