首页 / MongoDB 入门教程 / 查询空值与缺失字段

MongoDB 入门教程

查询空值与缺失字段

本教程共 50 篇 · 第 19 篇 · 更新于 2026-07-30 · 约 6 分钟阅读

MongoDBMongoDB 入门教程空值查询缺失字段nullexists

19. 查询空值与缺失字段

本节目标:弄懂 {字段: null} 为什么既匹配空值又匹配缺失,并学会用 $exists$type 把这两种情况精确分开。

「空值(null)」和「字段压根不存在」在 MongoDB 里是两回事,但查询时很容易混淆。我们先造一批带这两种情况的 users 数据:

db.users.insertMany([
  { _id: 1, name: "张三", age: 28, city: "北京", registered_at: ISODate("2024-01-15") },
  { _id: 2, name: "李四", age: 34, city: null, registered_at: ISODate("2024-03-20") },
  { _id: 3, name: "王五", age: 22, city: "北京" },
  { _id: 4, name: "赵六", age: 41, city: "广州", registered_at: null }
])

这里 _id:2city 是空值;_id:3 根本没有 registered_at 字段(缺失);_id:4registered_at 是空值。

{字段: null} 的双义性

直接用 null 去查,结果会超出你的预期:

// 既返回 city 为空值的,也返回根本没有 city 字段的
db.users.find({ city: null })

这条会命中 _id:2(city 是 null)和 _id:3(没有 city 字段)。因为 MongoDB 把「值为 null」和「字段不存在」都算作匹配。这个双义性经常让初学者一脸懵。

Warning

{ city: null } 不等于「city 是空值」。它其实是「city 是空值,或者压根没有 city」。想精准区分,必须加运算符。

只查「字段存在且非空」:$ne

如果想排除空值和缺失,用 $ne(不等于):

// 只要 city 存在并且不是 null 的文档
db.users.find({ city: { $ne: null } })

这条只命中 _id:1_id:4,它们都有真实城市值。

只查「字段缺失」:$exists: false

$exists 用来判断字段在不在。设为 false 就是「字段不存在」:

// 只找没有 registered_at 字段的用户
db.users.find({ registered_at: { $exists: false } })

这条只命中 _id:3。它不管值是什么,只关心字段在不在文档里。

Note

$exists: true 则相反,只匹配「字段存在」的文档,无论它的值是 null 还是别的东西。

只查「值为空」:$type: 10

BSON 里 null 有自己的类型编号,是 10。用 $type 可以只认空值:

// 只找 registered_at 的值真的是 null 的文档
db.users.find({ registered_at: { $type: 10 } })

这条只命中 _id:4。注意它不会命中缺失字段的文档,因为缺失字段谈不上「类型是 null」。

三种写法对比

一句话记住三兄弟的区别:

写法匹配空值匹配缺失
{ f: null }
{ f: { $ne: null } }否(只留存在的)
{ f: { $exists: false } }
{ f: { $type: 10 } }
Tip

实际开发里,我一般建议字段要么有值、要么是 null,别让它「时有时无」。统一了结构,查询时才不会掉进双义陷阱。

下章我们讲投影(Projection),也就是怎么控制查询「返回哪些字段」。