MongoDB不等于isn';t等于

MongoDB不等于isn';t等于,mongodb,mongodb-query,Mongodb,Mongodb Query,如果我运行以下命令: db.restaurants.find({'grades.grade': 'A'}, {'grades.grade':1}) 然后我返回所有评分为“a”的文档。也就是说,任何文件至少有一个“A”,但可能有其他等级。e、 g: { "_id" : ObjectId("56c9a7038cc7f52917313091"), "grades" : [ { &qu

如果我运行以下命令:

db.restaurants.find({'grades.grade': 'A'}, {'grades.grade':1})
然后我返回所有评分为“a”的文档。也就是说,任何文件至少有一个“A”,但可能有其他等级。e、 g:

{
    "_id" : ObjectId("56c9a7038cc7f52917313091"),
    "grades" : [ 
        {
            "grade" : "A"
        }, 
        {
            "grade" : "B"
        }, 
        {
            "grade" : "A"
        }, 
        {
            "grade" : "A"
        }
    ]
}
如果我使用
$ne
运算符:

db.restaurants.find({'grades.grade': {$ne: 'A'}}, {'grades.grade':1})
然后我返回所有等级不等于“A”的文档

e、 g

为什么
$ne
匹配所有等级,但等于匹配任何等级

注意:同样的行为似乎也适用于
$in
ans
$nin
$in
匹配任何文档,而
$nin
匹配所有文档

NB2:
$not
也表现出这种行为


我理解你的问题,我同意从功能的角度来看你是对的:应该有一种方法“否定”
等于
,在逻辑上是“给我任何包含非
a
的东西”

但我认为Mongo在这里的工作方式从形式逻辑的角度来看是有意义的。如果从逻辑上考虑,那么查询
db.restaurants.find({'grades.grade':'A'})
将返回

(grades[0].grade == 'A' || grades[1].grade == 'A' || grades[2].grade == 'A'|| grades[3].grade == 'A'...)
基本形式逻辑认为,对上述陈述的否定是正确的

(grades[0].grade != 'A' && grades[1].grade != 'A' && grades[2].grade != 'A'&& grades[3].grade != 'A'...)

这正是使用
$ne

得到的结果,这是基本的De Morgan逻辑否定的结果

非(A和B)指(非A)或(非B)

这可以直接转化为集合论,其中析取(OR)表示并集,合取(and)表示相交


当您应用equals时,您要求的是任何匹配的值(析取)。但当你否定它时,你就否定了德摩根所说的每一个匹配。

(x中的所有x,其中x==“A”)+(x中的所有x,其中x!=“A”)=XAye。Not是不包含在等式中的集合。因此,两者的计数将等于总文档数。但还是出乎意料。我同意这是出乎意料的。我只是想看看这种行为的逻辑。我的大脑思考得越多,它看起来就越“正确”。你的回答,而不是我所期望的。你在思考这个问题时的一大缺陷,在你的术语“文档”中是显而易见的。在每种情况下,只有一份文件,因此条件适用。数组本身不受单独条件的约束,也不应用于元素的任何组合。只有一个值与测试的
等级匹配。等级是否匹配。每个“文档”只需要一个条件为true,它是。将逻辑应用于阵列是一个完全不同的过程。
(grades[0].grade != 'A' && grades[1].grade != 'A' && grades[2].grade != 'A'&& grades[3].grade != 'A'...)