$exists
定义
$exists的
$exists运算符匹配包含或不含指定字段的文档,包括字段值为null的文档。
兼容性
您可以使用 $exists 对以下环境中托管的部署进行操作
MongoDB Atlas:云中MongoDB部署的全托管服务
MongoDB Enterprise:基于订阅的自托管MongoDB版本
MongoDB Community:源代码可用、免费使用且自托管的MongoDB版本
语法
要指定一个 $exists 表达式,使用以下原型
{ field: { $exists: <boolean> } }
当 <boolean> 为真时,$exists 匹配包含该字段的文档,包括字段值为 null 的文档。如果 <boolean> 为假,则查询返回不包含该字段的文档。[1]
| [1] | 用户不能再使用查询过滤器 $type: 0 作为 $exists:false 的同义词。要查询空或缺失的字段,请参阅查询空或缺失字段。 |
使用Atlas Search在Atlas中查询数据
对于存储在MongoDB Atlas中的数据,您可以在执行Atlas Search exists运算符时使用$search查询。在执行$search后运行$exists的性能低于直接使用exists运算符的$search。
要了解更多关于此运算符的Atlas Search版本信息,请参阅Atlas文档中的exists运算符。
示例
存在且不等于
考虑以下示例
db.inventory.find( { qty: { $exists: true, $nin: [ 5, 15 ] } } )
此查询将选择 inventory 集合中所有文档,其中存在 qty 字段,且其值不等于 5 或 15。
空值
以下示例使用名为 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 的同义词。要查询空或缺失的字段,请参阅查询空或缺失字段。
使用稀疏索引提高 $exists 性能
下表比较了使用稀疏索引和非稀疏索引进行 $exists 查询的性能
$exists 查询 | 使用稀疏索引 | 使用非稀疏索引 |
|---|---|---|
{ $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值。5缺少auditDate值。
在
auditDate字段上创建 稀疏索引db.getCollection( "stockSales" ).createIndex( { auditDate: 1 }, { name: "auditDateSparseIndex", sparse: true } ) 以下示例计算具有值的
auditDate字段(包括空值)的文档数,并使用 稀疏索引:db.stockSales.countDocuments( { auditDate: { $exists: true } } ) 示例返回 5。缺少
auditDate值的文档不计入。
提示
如果您只需要具有非空值的 field 的文档,您
可以使用
$ne: null而不是$exists: true。不需要在
field上创建 稀疏索引。
例如,使用 stockSales 集合
db.stockSales.countDocuments( { auditDate: { $ne: null } } )
示例返回 4。缺少 auditDate 值或具有空 auditDate 值的文档不计入。