首页/数据/NoSQL 速查/聚合条件表达式 $cond / $ifNull / $switch
MongoDB99 条

聚合条件表达式 $cond / $ifNull / $switch

管道内做条件分支:$cond 三元、$ifNull 兜底空值、$switch 多分支匹配,用于打标、分档与容错。

NoSQL 速查数据更新于 2026-10-13

管道里的条件表达式

聚合管道的条件表达式的用途是「算出一个值」而不是「过滤文档」:$cond 做二选一分支,$ifNull 给空值兜底,$switch 处理多分支。它们常出现在 $project 与 $addFields 里,用于打标、分档、补齐缺省值与容错,让输出结构直接可用。

基本信息

$cond{ $cond: { if, then, else } } 或数组写法 [条件, 真值, 假值]
$ifNull{ $ifNull: [值, 兜底值] },也可以提供多个候选值
$switch{ $switch: { branches: [ { case, then } ], default } }
适用位置$project、$addFields、$group 的累加表达式等
与查询条件区别条件表达式不参与筛选,过滤仍要靠 $match

典型使用场景

  • 分档打标:按金额或数量划分等级,输出枚举值供报表使用
  • 空值兜底:字段缺失或为 null 时统一填充占位值,避免前端出现空单元格
  • 多分支映射:按状态码或渠道映射为可读文案
  • 容错计算:分母为 0 时避免除零,返回空值或 0
  • 结构化输出:把多个字段拼成嵌套结构,减少应用层处理

示例

示例
db.orders.aggregate([
  { $project: {
      sku: 1,
      // 二选一分支:数量达到 100 记为 A 档
      grade: { $cond: [{ $gte: ["$qty", 100] }, "A", "B"] },
      // 空值兜底:备注缺失时输出占位符
      note: { $ifNull: ["$remark", "-"] },
      // 多分支:按状态码映射为可读文案,命中即停
      statusText: { $switch: { branches: [
        { case: { $eq: ["$status", 1] }, then: "待付款" },
        { case: { $eq: ["$status", 2] }, then: "已付款" }
      ], default: "其他" } },
      // 容错:分母为 0 时给出 0,避免除零得到 null
      ratio: { $cond: [{ $eq: ["$total", 0] }, 0, { $divide: ["$done", "$total"] }] }
  } }
])

表达式读法

表达式求值规则注意点
$cond(对象写法)条件为真取 then,否则取 elseelse 可省略,省略时结果为缺失
$cond(数组写法)第一个元素是条件条件必须是单个表达式,嵌套多层建议改用 $switch
$ifNull值为 null 或缺失时取兜底值只判断 null 与缺失,0 与空字符串不会触发
$switch按 branches 顺序求值,命中即停未命中且无 default 时字段不出现
$divide 与 $cond 组合先判断分母再计算直接相除遇到 0 会报错中断整个管道
$switch 的分支按书写顺序求值:把最常见或最具体的条件放前面,既省计算也更符合预期;所有分支都不命中且未提供 default 时,该字段不会出现在结果文档里。
条件表达式不减少进入管道的文档数:需要过滤时仍需 $match,把过滤逻辑写成条件表达式只会增加计算量。

易错点

  • $cond 数组写法里塞入多个条件表达式:语法不合法或语义不符预期,多分支应改用 $switch
  • 用 $ifNull 判断数值 0 或空字符串:它只识别 null 与缺失,为 0 的字段不会被替换成兜底值
  • 省略 $switch 的 default 分支:未命中时字段整体缺失,下游读取报错或显示空白
  • 在 $project 里用条件表达式过滤文档:文档没有减少,计算量全部保留,过滤必须用 $match

数据来源与参考

  • MongoDB Manual: $cond / $ifNull / $switch
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌