$or$or对由一个或多个表达式组成的大量执行逻辑OR操作,并选择至少满足一个表达式的文档。
兼容性
可以使用 $or 查找托管在以下环境中的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
$or 操作符的语法如下:
{ $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
考虑以下示例:
db.inventory.find( { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )
此查询会选择 inventory 集合中 quantity 字段值小于 20 或 price 字段值等于 10 的所有文档。
行为
$or 子句和索引
在评估 $or表达式中的子句时, MongoDB会执行集合扫描或索引扫描。如果索引支持所有子句, MongoDB将执行索引扫描。要使用索引计算 $or表达式,$or表达式中的所有子句都必须有索引支持。否则, MongoDB会执行集合扫描。
将索引与 $or 查询一起使用时,$or 的每个子句都可使用自己的索引。请考虑以下查询:
db.inventory.find( { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )
为支持此查询,应在 quantity 上创建一个索引,并在 price 上创建另一索引,而不是使用复合索引索引:
db.inventory.createIndex( { quantity: 1 } ) db.inventory.createIndex( { price: 1 } )
$or 和text 查询
如果$or 包含$text 查询,则$or 大量中的所有子句都必须有索引支持。这是因为$text 查询必须使用索引,而$or 仅当其所有子句都受索引支持时才能使用索引。如果$text 查询无法使用索引,则该查询将返回错误。
注意
$text 提供自管理(非 Atlas)部署的文本查询功能。对于托管在 MongoDB Atlas 上的数据,MongoDB 提供了一种改进的全文查询解决方案 Atlas Search。
$or 和地理空间查询
$or 支持地理空间子句。但是,如果您使用 near 子句($near 或 $nearSphere),则 $or 不能包含任何其他子句。使用仅包含一个子句的 $or 与省略 $or 操作符的效果相同。
例如,以下查询无效,因为 $or 操作符将 $near 与另一个子句组合在一起:
db.places.find( { $or: [ { location: { $near: [ 40, 5 ] } }, { category: "restaurant" } ] } )
以下查询是有效的,因为 $or 使用了非邻近地理空间子句 ($geoIntersects):
db.places.find( { $or: [ { location: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: [ [ [ 39, 4 ], [ 41, 4 ], [ 41, 6 ], [ 39, 4 ] ] ] } } } }, { category: "restaurant" } ] } )
$or 和排序操作
$or 和部分索引
您可以使用 $or 来创建部分索引。使用 db.collection.createIndex() 方法的 partialFilterExpression 来创建部分索引。
$or 相比于 $in
如果使用$or 和<expressions> 对同一字段的值进行相等性检查,请使用$in 而不是$or 。
此查询选择 inventory集合中的文档,其中 quantity 为 20 或 50:
db.inventory.find ( { quantity: { $in: [20, 50] } } )
嵌套$or 子句
您可以嵌套$or 操作。
Error Handling
要允许查询引擎优化查询,$or 会按如下方式处理错误:
如果提供给
$or的任何表达式在单独求值时会导致错误,则包含该表达式的$or可能但不一定会导致错误。在提供给
$or的第一个表达式之后提供的表达式可能会导致错误,即使第一个表达式的计算结果为true。
例如,如果 $x 为 0,以下查询会始终产生错误:
db.example.find( { $expr: { $eq: [ { $divide: [ 1, "$x" ] }, 3 ] } } )
以下查询包含提供给 $or 的多个表达式,如果存在 $x 为 0 的任何文档,则查询可能会产生错误:
db.example.find( { $or: [ { x: { $eq: 0 } }, { $expr: { $eq: [ { $divide: [ 1, "$x" ] }, 3 ] } } ] } )