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
相关产品推荐
相关产品推荐

