Docs 菜单
Docs 主页
/
数据库手册
/ / / /

$and

$and

$and 对由一个或多个表达式(<expression1><expression2> 等)组成的数组执行逻辑 AND 操作,并选择满足所有表达式的文档。

注意

指定用逗号分隔的表达式列表时,MongoDB 提供隐式 AND 操作。

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

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

  • MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本

  • MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本

$and 采用以下语法:

{ $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }

在评估 $and 表达式中的子句时,MongoDB 的查询优化器会考虑哪些可用索引在选择要执行的最佳计划时有助于满足 $and 表达式的子句。

要允许查询引擎优化查询,$and 会按如下方式处理错误:

  • 如果提供给 $and 的任何表达式在单独求值时会导致错误,则包含该表达式的 $and 可能但不一定会导致错误。

  • 在提供给 $and 的第一个表达式之后提供的表达式可能会导致错误,即使第一个表达式的计算结果为 false

例如,如果 $x0,以下查询会始终产生错误:

db.example.find( {
$expr: { $eq: [ { $divide: [ 1, "$x" ] }, 3 ] }
} )

以下查询包含提供给 $and 的多个表达式,如果存在 $x0 的任何文档,则查询可能会产生错误:

db.example.find( {
$and: [
{ x: { $ne: 0 } },
{ $expr: { $eq: [ { $divide: [ 1, "$x" ] }, 3 ] } }
]
} )

大多数编程语言和驱动程序,包括MongoDB Shell mongosh(),都不允许在同一对象级别构造具有重复键的对象。示例,考虑以下查询:

db.inventory.find( { price: { $in: [ 7.99, 3.99 ], $in: [ 4.99, 1.99 ] } } )

上述查询构造不正确,因为字段名 price 在同一对象级别包含重复的操作符。因此,发送到服务器的查询与预期不同。为使查询按预期运行,请使用显式 AND操作符:

db.inventory.find( {
$and: [
{ price: { $in: [ 7.99, 3.99 ] } },
{ price: { $in: [ 4.99, 1.99 ] } }
]
} )

此查询显式检查这两个条件是否均已满足:price 大量必须至少包含每个$in 设立中的一个值。有关如何解决此类情况的更多信息,请参阅“示例”部分。

请考虑以下查询:

db.inventory.find( { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] } )

该查询选择 inventory 集合中满足如下条件的所有文档:

  • price 字段值不等于 1.99 并且

  • price 字段存在。

您可以简化此查询,方法是使用嵌套隐式 ANDprice字段的操作符表达式组合成单个查询对象:

db.inventory.find( { price: { $ne: 1.99, $exists: true } } )

有时,此类重写是不可能的,尤其是在处理同一字段上的重复条件时。示例:

db.inventory.find( { status: { $ne: "closed", $ne: "archived" } } )

上述查询无法正确构造,因为它在同一对象级别的同一 字段名称上多次使用$ne status操作符。在这种情况下,$nin 操作符提供了更有效的解决方案:

db.inventory.find( { status: { $nin: [ "closed", "archived" ] } } )

如何重写查询取决于使用案例的预期语义。考虑以下查询:

db.inventory.find( {
$and: [
{ status: "new" },
{ status: "processing" }
]
} )

如果要查找statusnewprocessing 的文档,可以使用$in 操作符:

db.inventory.find( { status: { $in: [ "new", "processing" ] } } )

如果status 字段是大量[ "new", "processing" ] ,并且您想要检查文档是否同时包含newprocessing 值,请使用$all 操作符:

db.inventory.find( { status: { $all: [ "new", "processing" ] } } )

在这种情况下,此查询在语义上等同于AND ,但在查询大量字段时,$all 通常更清晰。

与重复字段名称类似,相同的注意事项应用于查询中使用的重复运算符。

提示

后退

逻辑

在此页面上