$ifnull仅在字段不存在或值为null时生效;对空字符串、0、false不触发默认值。它只响应undefined和显式null,不将""、0、false视为“空”,这是初学者最常误判之处。

$ifNull 不是“兜底万能药”,它只在字段 完全不存在 或值为 null 时生效;如果字段存在且值是空字符串 ""、0、false,它不会触发默认值。
什么时候 $ifNull 才真正起作用?
它只响应两种情况:undefined(字段压根没写)和显式存入的 null。MongoDB 不会把 ""、0、false 当作“空”来处理——这是初学者最常误判的地方。
- 文档
{ name: "Alice" }→$ifNull: ["$age", 0]返回0(因为"age"字段不存在) - 文档
{ name: "Bob", age: null }→ 同样返回0 - 文档
{ name: "Charlie", age: "" }→ 返回"",不是0 - 文档
{ name: "David", age: 0 }→ 返回0(原始值),不是默认值
在聚合管道里怎么安全地补缺字段?
最常用位置是 $project 阶段,但要注意嵌套字段必须用完整路径,且不能省略引号。
{
$project: {
fullName: { $ifNull: ["$profile.fullName", "$name"] },
email: { $ifNull: ["$contact.email", "no-email@example.com"] }
}
}
- 路径写错(比如写成
"profile.fullname"而不是"$profile.fullName")会导致整个字段为null,进而被再次$ifNull捕获,逻辑错乱 - 若
$profile本身不存在,"$profile.fullName"计算结果是undefined,仍可被$ifNull捕获 - 不要试图在
$ifNull第一个参数里写表达式(如{ $toString: "$age" }),它只接受字段路径或字面量
和 $cond 比,什么情况下该换用 $cond?
当你需要区分“字段不存在”、“字段为 null”、“字段为空字符串”这几种情况时,$ifNull 就不够用了,得上 $cond。
{
$project: {
displayEmail: {
$cond: {
if: { $eq: ["$contact.email", ""] },
then: "email-missing",
else: { $ifNull: ["$contact.email", "no-contact"] }
}
}
}
}
-
$ifNull是二元判断,$cond是三元(或嵌套多层),适合做更细粒度的空值分类 - 性能上
$ifNull更轻量,无必要别一上来就套$cond - 注意
$eq对null和undefined的比较行为:两者互不相等,所以{ $eq: ["$x", null] }不会匹配字段缺失的情况
真正麻烦的从来不是语法,而是你默认认为“空 = 缺失”。查数据前先 db.collection.findOne({}) 看一眼真实字段值类型,比背函数文档管用得多。











