$exists
定义
$exists
$exists
运算符匹配包含或不包含指定字段的文档,包括字段值为null
的文档。
兼容性
可以使用 $exists
查找托管在以下环境中的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
要指定 $exists
表达式,请使用以下原型:
{ field: { $exists: <boolean> } }
当 <boolean>
为 true 时,$exists
匹配包含该字段的文档,包括字段值为 null
的文档。如果 <boolean>
为 false,则查询仅返回不包含该字段的文档。[1]
[1] | 用户不能再使用查询过滤器 $type: 0 作为 $exists:false 的同义词。要查询 null 字段或缺失字段,请参阅查询 null 字段或缺失字段。 |
使用 Atlas Search 查询 Atlas 数据
对于存储在 MongoDB Atlas 中的数据,您可以在运行 $search
查询时使用 Atlas Search 和 exists 操作符。在 $search
之后运行 $exists
的性能低于使用 exists 操作符运行 $search
。
要了解有关此操作符的 Atlas Search 版本的详情,请参阅 Atlas 文档中的 exists 操作符。
示例
存在且不等于
考虑以下示例:
db.inventory.find( { qty: { $exists: true, $nin: [ 5, 15 ] } } )
此查询将选择 inventory
集合中存在 qty
字段且其值不等于 5
或 15
的所有文档。
Null Values
以下示例使用了一个名为 spices
的集合,其中包含以下文档:
db.spices.insertMany( [ { saffron: 5, cinnamon: 5, mustard: null }, { saffron: 3, cinnamon: null, mustard: 8 }, { saffron: null, cinnamon: 3, mustard: 9 }, { saffron: 1, cinnamon: 2, mustard: 3 }, { saffron: 2, mustard: 5 }, { saffron: 3, cinnamon: 2 }, { saffron: 4 }, { cinnamon: 2, mustard: 4 }, { cinnamon: 2 }, { mustard: 6 } ] )
$exists: true
以下查询将指定查询谓词 saffron: { $exists: true }
:
db.spices.find( { saffron: { $exists: true } } )
结果由包含字段 saffron
的文档组成,包括字段 saffron
包含空值的文档:
{ saffron: 5, cinnamon: 5, mustard: null } { saffron: 3, cinnamon: null, mustard: 8 } { saffron: null, cinnamon: 3, mustard: 9 } { saffron: 1, cinnamon: 2, mustard: 3 } { saffron: 2, mustard: 5 } { saffron: 3, cinnamon: 2 } { saffron: 4 }
$exists: false
以下查询将指定查询谓词 cinnamon: { $exists: false }
:
db.spices.find( { cinnamon: { $exists: false } } )
结果由不包含字段 cinnamon
的文档组成:
{ saffron: 2, mustard: 5 } { saffron: 4 } { mustard: 6 }
用户不能再使用查询过滤器 $type: 0
作为 $exists:false
的同义词。要查询 null 字段或缺失字段,请参阅查询 null 字段或缺失字段。
使用稀疏索引提高$exists
性能
下表比较使用稀疏索引和非稀疏索引的 $exists
查询性能:
$exists 查询 | 使用稀疏索引 | Using a Non-Sparse Index |
---|---|---|
{ $exists: true } | 最高效。MongoDB 可以进行精确匹配,不需要 FETCH 。 | 比不含索引的查询更高效,但仍需 FETCH 。 |
{ $exists: false } | 无法使用索引,需要 COLLSCAN 。 | 需要使用 FETCH 。 |
以下查询检查集合中的所有文档:对使用非稀疏索引的字段使用 { $exists: true }
或对未编入索引的字段使用 { $exists: true }
。为了提高性能,请在 field
上创建稀疏索引,如以下场景所示:
创建一个
stockSales
集合:db.stockSales.insertMany( [ { _id: 0, symbol: "MDB", auditDate: new Date( "2021-05-18T16:12:23Z" ) }, { _id: 1, symbol: "MDB", auditDate: new Date( "2021-04-21T11:34:45Z" ) }, { _id: 2, symbol: "MSFT", auditDate: new Date( "2021-02-24T15:11:32Z" ) }, { _id: 3, symbol: "MSFT", auditDate: null }, { _id: 4, symbol: "MSFT", auditDate: new Date( "2021-07-13T18:32:54Z" ) }, { _id: 5, symbol: "AAPL" } ] ) _id
为以下值的文档:3
的auditDate
值为 null。5
缺少auditDate
值。
在
auditDate
字段上创建稀疏索引:db.getCollection( "stockSales" ).createIndex( { auditDate: 1 }, { name: "auditDateSparseIndex", sparse: true } ) 以下示例计算
auditDate
字段具有值(包括 null)并使用稀疏索引的文档:db.stockSales.countDocuments( { auditDate: { $exists: true } } ) 该示例返回 5。缺少
auditDate
值的文档不计入在内。
提示
如果只需 field
具有非空值的文档,您可以:
可以使用
$ne: null
代替$exists: true
。不需要在
field
上使用稀疏索引。
例如,使用 stockSales
集合:
db.stockSales.countDocuments( { auditDate: { $ne: null } } )
该示例返回 4。缺少 auditDate
值或 auditDate
值为 null 的文档不计入在内。