MongoDB中不存储字段与存储字段为null是否存在差异?
MongoDB中不存储字段与存储null的差异对比
核心差异概述
不存储某个字段和将该字段设为null在MongoDB里是完全不同的两种状态,主要差异体现在查询逻辑、存储开销、索引行为等多个维度,具体拆解如下:
1. 查询行为的区别
- 使用
{ B: null }查询时,会同时匹配两类文档:字段B不存在的文档,以及字段B存在且值为null的文档。若要精准匹配字段B为null的文档,需用{ B: { $type: 10 } }(10是MongoDB中null的类型码);若只想匹配字段B不存在的文档,要用{ B: { $exists: false } }。 - 反之,
{ B: { $exists: true } }只会匹配包含字段B的文档,无论其值是否为null。
2. 存储与索引的差异
- 文档大小:包含
B: null的文档比不包含B字段的文档占用更多存储空间(null本身占用空间极小,但字段名会占用额外字节)。 - 索引占用:若给字段B创建索引,
B: null的文档会在索引中占据一条记录;而不包含B字段的文档不会出现在该索引中,这会直接影响索引的大小与查询效率。
3. 更新操作的差异
- 给文档新增字段B并设为null,需执行
db.collection.updateOne({A:1}, {$set: {B: null}}),操作后文档会明确包含B字段;若要移除B字段,需用db.collection.updateOne({A:1}, {$unset: {B: ""}}),操作后B字段会被彻底删除。 - 使用
$set更新不存在的字段时,会自动添加该字段;但如果字段已设为null,后续更新需明确指定修改该字段的值。
两个示例文档的具体区别
对比以下两个文档:
文档1:
{ "A": 1, "B": null }文档2:
{ "A": 1 }
它们的核心区别如下:
- 字段存在性:文档1明确包含字段B,值为null;文档2完全没有B字段。
- 查询匹配:
{ B: null }会同时匹配两个文档;但{ B: { $exists: true } }仅匹配文档1,{ B: { $exists: false } }仅匹配文档2。 - 索引表现:若给B字段建索引,文档1会出现在索引中,文档2不会。
- 存储大小:文档1的存储空间略大于文档2(多了字段名"B"的存储开销)。
内容的提问来源于stack exchange,提问作者Bear Bile Farming is Torture
相关产品推荐
相关产品推荐

