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

MongoDB无匹配数据时返回默认值的实现方法

MongoDB聚合查询:无匹配数据时返回默认结果

问题描述

用户现有聚合查询用于统计指定meal ID中未完成(mealsStatus不等于'SERVED')的订单数量,代码如下:

db.meals
      .aggregate([
        {
          $match: {
            _id: { $in: [ObjectId('123'), ObjectId('1234')]},
            mealsStatus: { $ne: 'SERVED' },
          },
        },
        {
          $group: {
            _id: '$orderId',
            orderCount: { $sum: 1 },
          },
        },
      ])

当前问题:当没有数据匹配$match条件时,查询无任何返回结果。需要修改查询,使其返回指定ID对应的默认数据,格式示例如下:

{
   '_id': '123',
   'orderCount': 0
},
{
   '_id': '1234',
   'orderCount': 0
}

解决方案

要实现无匹配时返回默认值,可通过合并实际统计结果与默认数据集的方式实现,以下提供两种适配不同MongoDB版本的方案:

方案1:使用$unionWith(MongoDB 4.4+)

该方案通过$unionWith合并实际统计结果与构造的默认数据集,再去重保留有效数值:

const targetMealIds = [ObjectId('123'), ObjectId('1234')];

db.meals.aggregate([
  // 原有统计逻辑:获取匹配数据的订单数量
  {
    $match: {
      _id: { $in: targetMealIds },
      mealsStatus: { $ne: 'SERVED' }
    }
  },
  {
    $group: {
      _id: '$_id',
      orderCount: { $sum: 1 }
    }
  },
  // 合并默认数据集:生成所有指定ID的默认文档(orderCount=0)
  {
    $unionWith: {
      coll: 'meals',
      pipeline: [
        { $project: { _id: 0, mealId: { $literal: targetMealIds } } },
        { $unwind: '$mealId' },
        { $project: { _id: '$mealId', orderCount: { $literal: 0 } } }
      ]
    }
  },
  // 去重处理:优先保留实际统计值,无统计值则保留默认0
  {
    $group: {
      _id: '$_id',
      orderCount: { $max: '$orderCount' }
    }
  }
])
  • 核心逻辑:$max会优先取实际统计的正数值,无统计结果时则保留默认的0,确保每个指定ID都有返回。

方案2:使用$facet(兼容MongoDB 4.4以下版本)

通过$facet同时处理实际统计和默认数据,再合并去重:

const targetMealIds = [ObjectId('123'), ObjectId('1234')];

db.meals.aggregate([
  {
    $facet: {
      // 统计有匹配的数据
      actualCounts: [
        {
          $match: {
            _id: { $in: targetMealIds },
            mealsStatus: { $ne: 'SERVED' }
          }
        },
        {
          $group: {
            _id: '$_id',
            orderCount: { $sum: 1 }
          }
        }
      ],
      // 生成默认数据集
      defaultCounts: [
        { $limit: 1 },
        { $project: { _id: 0, mealIds: { $literal: targetMealIds } } },
        { $unwind: '$mealIds' },
        { $project: { _id: '$mealIds', orderCount: { $literal: 0 } } }
      ]
    }
  },
  // 合并两个结果数组
  { $project: { combined: { $concatArrays: ['$actualCounts', '$defaultCounts'] } } },
  { $unwind: '$combined' },
  // 去重并保留有效数值
  {
    $group: {
      _id: '$combined._id',
      orderCount: { $max: '$combined.orderCount' }
    }
  }
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:50:20