$switch是表达式运算符,必须嵌套在$project或$addFields等支持表达式的阶段中,不能单独作为聚合管道阶段;各case需为布尔表达式,default必填,分支过多时应拆解或移至应用层处理。

$switch 必须写在 $project 或 $addFields 里
单独用 $switch 不会生效,它不是管道阶段,而是表达式运算符,只能嵌套在支持表达式的阶段中。最常用的是 $project 和 $addFields(或 $set),用于生成新字段或重写现有字段。
常见错误是把它直接丢进聚合数组顶层,比如这样写会报错:
db.collection.aggregate([
{ $switch: { ... } }, // ❌ 错误:这不是合法阶段
{ $group: { ... } }
])
正确做法是包裹一层 $project:
db.collection.aggregate([
{
$project: {
statusLabel: {
$switch: {
branches: [
{ case: { $eq: ["$status", "active"] }, then: "在线" },
{ case: { $eq: ["$status", "inactive"] }, then: "离线" },
{ case: { $eq: ["$status", "pending"] }, then: "待审核" }
],
default: "未知"
}
}
}
}
])
分支条件必须是布尔表达式,不能直接写字符串匹配
$switch 的每个 case 字段必须返回 true 或 false,不能写成 "active" 这样的字面量。否则整个分支永远不命中,全部走 default。
- ✅ 正确:
{ case: { $eq: ["$status", "active"] }, then: "在线" } - ❌ 错误:
{ case: "active", then: "在线" }(MongoDB 会静默忽略该 branch) - ⚠️ 注意:
$eq第一个参数必须是字段路径(带$)或表达式,不能漏掉引号或写错层级,比如"status"(没加$)就查不到字段
default 是必填项,不填会报错
$switch 的 default 字段不是可选的——即使你认为所有情况都已覆盖,也必须显式声明。缺失时 MongoDB 直接抛出 errmsg: "Unrecognized expression '$switch'" 类似错误(实际是解析失败,但错误信息不直观)。
智能模型自动切换 V5.0.2 - 多模态感知,自动识别图片/视频/音频/代码/文本任务,切换最优模型。支持图片理解(qwen3-vl-plus)、视频音频(qwen3.5-plus)、代码(glm-5)、Office文档(MiniMax-M2.5)、推理等场景。零感知切换,无需手动操作。
如果你确实不想设默认值,可以填一个空字符串、null,或用 $literal 显式构造:
default: { $literal: null }
另外注意:如果所有 case 都为 false,且没写 default,整个表达式求值失败,对应文档该字段会消失(不是 null,是字段不存在),这在后续 $group 或应用层取值时容易引发空指针类问题。
嵌套太深或分支太多会影响可读性和调试效率
超过 5–7 个分支时,$switch 很快变得难维护。别硬撑,优先考虑是否能拆解:
- 把一部分逻辑提前用
$match过滤掉,减少进入$switch的文档量 - 用
$cond套$cond处理二元判断(适合 if-else 链),比大段$switch更紧凑 - 若分支基于同一字段的枚举值,且数量稳定,可配合
$in+$cond组合简化,例如区分 “高/中/低” 优先级
真正复杂的状态机逻辑(比如含顺序依赖、中间变量),建议放到应用层处理——聚合管道不是图灵完备的编程环境,强行塞进去只会让执行计划变慢、出错难定位。

















