使用两个子句的Mongo查询工作不正常。它遵循以下模式:
var aDate = ISODate("2020-09-09T16:50:00.000Z");
db.col.find({
$or: [ { deletedBy: 'joe', markedBy: 'joe' } ],
$or: [ { deletedOn: {$lte: aDate}, markedOn: {$lte: aDate} ]
})
这应该返回字段deletedBy or markedBy contains 'joe'
ANDthe field deletedOn or markedOn is less than or equal to the aDate
变量所在的文档。
我认为mongo使用AND
运算符处理多个字段,因此只有当a == 1
和b == 2
都为真时,{a:1,b:2}
才会为真。mongo文档就是这样描述的。请参阅https://docs.mongodb.com/manual/reference/method/db.collection.find/#query-用于多种条件。
当我将查询更改为显式声明$and
运算符时,查询产生了正确的结果。
var aDate = ISODate("2020-09-09T16:50:00.000Z");
db.col.find({
$and: [ { $or: [ { deletedBy: 'joe', markedBy: 'joe' } ] },
{ $or: [ { deletedOn: {$lte: aDate}, markedOn: {$lte: aDate} ] }
]
})
我使用一些调试打印语句证明了查询产生了不正确的结果,如下所示。我用上面显示的每个查询测试了这一点。
var aDate = ISODate("2020-09-09T16:50:00.000Z");
db.col.find({
$or: [ { deletedBy: 'joe', markedBy: 'joe' } ],
$or: [ { deletedOn: {$lte: aDate}, markedOn: {$lte: aDate} ]
})
.forEach(function(doc) {
if (doc.deletedBy && doc.deletedBy !== 'joe') {
print('deletedBy not set to joe. deletedBy=' + doc.deletedBy + ', markedBy: ' + doc.markedBy);
}
if (doc.markedBy && doc.markedBy!== 'joe') {
print('markedBy not set to joe. markedBy =' + doc.markedBy + ', markedBy: ' + doc.markedBy);
}
if (doc.deletedOn && doc.deletedOn > aDate) {
print('deletedOn check: deletedOn=' + doc.deletedOn + ', markedOn=' + doc.markedOn);
}
if (doc.markedOn&& doc.markedOn> aDate) {
print('markedOncheck: markedOn=' + doc.markedOn+ ', deletedOn =' + doc.deletedOn );
}
});
print语句将打印显示deletedBy是"joe"以外的值的文档。例如,
deletedBy not set to joe. deletedBy=sally, markedBy: undefined
deletedBy not set to joe. deletedBy=mark, markedBy: undefined
但是当我使用$and
运算符时,这些打印语句不会出现!
所以我的问题是:我什么时候必须使用AND
运算符来获得正确的查询结果,它在哪里记录
以下是我在搜索答案时发现的东西
我进行了搜索,但这只是证实了我的理解是正确的,我不知道为什么我需要添加$,并且需要运算符(在我的情况下(。看见https://docs.mongodb.com/manual/reference/operator/query/and/index.html上面写着:
注意:MongoDB在指定逗号分隔的表达式列表时提供了一个隐式AND操作
另请参阅:Mongo-db查询带有和,这实际上是一个不同的问题。
您尝试的第一个查询不起作用的原因只是对象不能有两个同名的属性,所以
{
$or: [ { deletedBy: 'joe', markedBy: 'joe' } ],
$or: [ { deletedOn: {$lte: 1}, markedOn: {$lte: 2} } ]
}
变成了
{ $or: [ { deletedOn: {$lte: 1}, markedOn: {$lte: 2} ] }
甚至在它被传给蒙戈之前。
编辑:还有,你的期望"这应该返回字段deletedBy或markedBy包含'joe'并且字段deletedOn或markedOn小于或等于aDate变量"的文档;也不正确。对于$or
表达式,您需要将它们分离为不同的数组元素,因此$or: [ { deletedBy: 'joe', markedBy: 'joe' } ]
将变为$or: [ { deletedBy: 'joe' }, { markedBy: 'joe' } ]
。