MongoDB:两个 $or 与隐式 AND 组合 - 预期行为?

标签 mongodb mongodb-query

在 MongoDB 文档中是这样说的

db.inventory.find( {
  $and : [
      { $or : [ { price : 0.99 }, { price : 1.99 } ] },
      { $or : [ { sale : true }, { qty : { $lt : 20 } } ] }
  ]
})

This query cannot be constructed using an implicit AND operation, because it uses the $or operator more than once.

https://docs.mongodb.com/manual/reference/operator/query/and/

如果您确实使用隐式 AND 来表示两个 OR,您会期待什么?行为是否明确定义?

从这个实验来看,它似乎忽略了第一个 OR 谓词..

> db.mytest.insertMany([
{w: 0,  x: 0, y: 0, z: 0 },
{w: 0,  x: 0, y: 1, z: 0 },
{w: 0,  x: 0, y: 1, z: 1 },
{w: 0,  x: 1, y: 0, z: 0 },
{w: 0,  x: 1, y: 0, z: 1 },
{w: 0,  x: 1, y: 1, z: 0 },
{w: 0,  x: 1, y: 1, z: 1 },
{w: 1,  x: 0, y: 0, z: 0 },
{w: 1,  x: 0, y: 1, z: 0 },
{w: 1,  x: 0, y: 1, z: 1 },
{w: 1,  x: 1, y: 0, z: 0 },
{w: 1,  x: 1, y: 0, z: 1 },
{w: 1,  x: 1, y: 1, z: 0 },
{w: 1,  x: 1, y: 1, z: 1 },
])
...
>db.mytest.find({$or: [ {w: 1}, { x: 1} ],$or: [ {y: 1}, { z: 1} ]})
{ "_id" : ObjectId("59ce696828f7ac6a3372e64d"), "w" : 0, "x" : 0, "y" : 1, "z" : 0 }
{ "_id" : ObjectId("59ce696828f7ac6a3372e64e"), "w" : 0, "x" : 0, "y" : 1, "z" : 1 }
{ "_id" : ObjectId("59ce696828f7ac6a3372e650"), "w" : 0, "x" : 1, "y" : 0, "z" : 1 }
{ "_id" : ObjectId("59ce696828f7ac6a3372e651"), "w" : 0, "x" : 1, "y" : 1, "z" : 0 }
{ "_id" : ObjectId("59ce696828f7ac6a3372e652"), "w" : 0, "x" : 1, "y" : 1, "z" : 1 }
{ "_id" : ObjectId("59ce696828f7ac6a3372e654"), "w" : 1, "x" : 0, "y" : 1, "z" : 0 }
{ "_id" : ObjectId("59ce696828f7ac6a3372e655"), "w" : 1, "x" : 0, "y" : 1, "z" : 1 }
{ "_id" : ObjectId("59ce696828f7ac6a3372e657"), "w" : 1, "x" : 1, "y" : 0, "z" : 1 }
{ "_id" : ObjectId("59ce696828f7ac6a3372e658"), "w" : 1, "x" : 1, "y" : 1, "z" : 0 }
{ "_id" : ObjectId("59ce696828f7ac6a3372e659"), "w" : 1, "x" : 1, "y" : 1, "z" : 1 }
> 

我问这个问题是因为在我看来这种行为不一致。我错误地在代码中的几个地方使用了隐式 AND 和 OR。其中之一似乎给出了与您使用显式 AND 所期望的相同的答案。这是一个复杂的查询,所以我可能在查询或测试中犯了错误。很高兴知道这里发生了什么......可能还有另一个错误需要我清除。

最佳答案

MongoDB 对待

{$or: [ {w: 1}, { x: 1} ],$or: [ {y: 1}, { z: 1} ]}

作为

{$or: [ {y: 1}, { z: 1} ]}

当 MongoDB 查询中 2 个键相同时,最新的键将替换较早的键。

docs 中所述,您将需要一个明确的 $and

关于MongoDB:两个 $or 与隐式 AND 组合 - 预期行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46503004/

相关文章:

jquery - 如何根据使用 jQuery 从 Mongo 文档发送的信息使 HTML 下拉菜单具有默认选择的选项?

javascript - 在 mongo javascript 中使用变量

python - 清理 MongoDB 的输入

javascript - MongoDB $project 嵌入文档到根级别

python - 使用 Python 插入到具有唯一键的 MongoDB 集合

node.js - 如何在单个 mongo 查询中将一个字段的值分配给另一个字段

node.js - 如何对 Mongoose 中的结果数组进行排序和限制?

php - MongoDB + PHP 无并发

mongodb - float 在聚合中不匹配

python - MongoDB 搜索集合中列表中的每个字典