Docs 菜单

Docs 主页开发应用程序MongoDB Manual

$exists

在此页面上

  • 定义
  • 兼容性
  • 语法
  • 使用 Atlas Search 查询 Atlas 数据
  • 举例
  • 存在且不等于
  • Null 值
  • 使用稀疏索引提高 $exists 性能
$exists

$exists操作符匹配包含或不包含指定字段的文档,包括字段值为null的文档。

注意

MongoDB $exists 与 SQL 操作符 exists 对应。关于 SQL exists,请参阅 $in 操作符。

对于 Atlas Search exists ,请参阅 Atlas 文档中的exists操作符。

提示

另请参阅:

可以使用 $exists 查找托管在以下环境中的部署:

  • MongoDB Atlas :用于在云中部署 MongoDB 的完全托管服务

要指定$exists表达式,请使用以下原型:

{ field: { $exists: <boolean> } }

<boolean>为 true 时, $exists会匹配包含该字段的文档,包括字段值为null的文档。如果<boolean>为 false,则查询仅返回不包含该字段的文档。 [ 1 ]

[1] 从 MongoDB 4.2 开始,用户不能再使用查询筛选器 $type: 0 作为 $exists:false 的同义词。要查询空值字段或缺失字段,请参阅《查询空值字段或缺失字段》

对于存储在 MongoDB Atlas 中的数据,您可以在运行 查询时使用 Atlas Search exists $search操作符。在$exists $search}$search 之后运行 的性能低于使用 exists 操作符运行 。

要了解有关此操作符的 Atlas Search 版本的更多信息,请参阅 Atlas 文档中的exists操作符。

考虑以下示例:

db.inventory.find( { qty: { $exists: true, $nin: [ 5, 15 ] } } )

此查询将选择 inventory 集合中存在 qty 字段其值不等于 515 的所有文档。

以下示例使用了一个名为 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 }
] )

以下查询将指定查询谓词 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 }

以下查询将指定查询谓词 cinnamon: { $exists: false }

db.spices.find( { cinnamon: { $exists: false } } )

结果由不包含字段 cinnamon 的文档组成:

{ saffron: 2, mustard: 5 }
{ saffron: 4 }
{ mustard: 6 }

从 MongoDB 4.2 开始,用户不能再使用查询筛选器 $type: 0 作为 $exists:false 的同义词。要查询空值字段或缺失字段,请参阅《查询空值字段或缺失字段》

下表比较使用稀疏索引和非稀疏索引的 $exists 查询性能:

$exists 查询
使用稀疏索引
使用非稀疏索引
{ $exists: true }
最高效。MongoDB 可以进行精确匹配,不需要 FETCH
比不含索引的查询更高效,但仍需FETCH
{ $exists: false }
无法使用索引,需要 COLLSCAN
需要使用 FETCH

以下查询检查集合中的所有文档:对使用非稀疏索引的字段使用 { $exists: true } 或对未编入索引的字段使用 { $exists: true }。为了提高性能,请在 field 上创建稀疏索引,如以下场景所示:

  1. 创建一个 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 为以下值的文档:

    • 3auditDate 值为 null。

    • 5 缺少 auditDate 值。

  2. auditDate 字段上创建稀疏索引

    db.getCollection( "stockSales" ).createIndex(
    { auditDate: 1 },
    { name: "auditDateSparseIndex", sparse: true }
    )
  3. 以下示例计算 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 的文档不计入在内。

提示

← 元素查询操作符
$type →