Mongodb 如何在对象数组中没有精确对象的情况下搜索文档?

Mongodb 如何在对象数组中没有精确对象的情况下搜索文档?,mongodb,mongoose,Mongodb,Mongoose,我有一个人员集合,其模式类似于以下文档的集合 Document: { name: age: educations:[{ title:xyz, passed_year:2005, univercity:abc}, { title:asd passed_year:2007, univercity:mno }], current_city:ghi } 现在我想展示一下所有在2005年没有接受过abc大学xyz教育的人 我认为这需要两个可能的查询,但不确定使用哪一个,

我有一个人员集合,其模式类似于以下文档的集合

    Document: {

    name:
    age:
    educations:[{
title:xyz,
passed_year:2005,
univercity:abc},
{
title:asd
passed_year:2007,
univercity:mno
}],
current_city:ghi
}
现在我想展示一下所有在2005年没有接受过abc大学xyz教育的人

我认为这需要两个可能的查询,但不确定使用哪一个,因为它们都提供了输出

查询1:

db.persons.find({“教育”:{$ne:{$elemMatch:{“头衔”:“xyz”,“通过年份”:2005,“大学”:“abc”}})

查询2:

db.persons.find({“教育”:{$not:{$elemMatch:{“头衔”:“xyz”,“通过年份”:2005,“大学”:“abc”}})


我对运算符$ne和$not感到非常困惑,我应该使用哪一个与$elemMatch一起使用,因为它们都给我输出。

鉴于此,
$elemMatch
{“title”:“xyz”,“passed_year”:2005,“univercity”:“abc”}
我认为您希望排除包含教育数组中的子文档的任何文档,该数组包含所有这些对:

  • “标题”:“xyz”
  • “过去的一年”:2005年
  • “大学城”:“abc”
此查询将实现以下目标:

db.persons.find({
    "educations": {
        $not: {
            $elemMatch:{"title": "xyz", "passed_year": 2005, "univercity": "abc"}
         }
     }
})
你在问题中写道:

他们两个都给了我输出

我怀疑这是因为您的查询指定的是
教育
,而正确的属性名称是
教育
。通过指定
education
,您添加了一个无法计算的谓词,因为它引用了一个不存在的文档属性,因此无论该谓词使用
$ne
还是
$not
,它都不会被应用

在回答使用哪个操作符的问题时:
$not
$ne
:如果您使用
.explain(true)
运行上述查询,您会注意到Mongo生成的解析查询对于每个操作符都非常不同

  • 使用
    $ne

    "parsedQuery" : {
        "$not" : {
            "educations" : {
                "$eq" : {
                    "$elemMatch" : {
                        "title" : "xyz",
                        "passed_year" : 2005,
                        "univercity" : "abc"
                    }
                }
            }
        }
    }
    
  • 使用
    $not

    "parsedQuery" : {
        "$not" : {
            "educations" : {
                "$elemMatch" : {
                    "$and" : [ 
                        {
                            "passed_year" : {
                                "$eq" : 2005
                            }
                        }, 
                        {
                            "title" : {
                                "$eq" : "xyz"
                            }
                        }, 
                        {
                            "univercity" : {
                                "$eq" : "abc"
                            }
                        }
                    ]
                }
            }
        }
    }
    
因此,使用
$ne
似乎会导致Mongo执行类似于此psuedo代码的操作

not educations equalTo "$elemMatch" : {"title" : "xyz", "passed_year" : 2005, "univercity" : "abc"}

。。。i、 e.它将elemMatch子句视为相等运算的RHS,而使用
$not
会导致Mongo实际计算elemMatch子句。

感谢@glitch纠正我的错误,但我想再问一个问题,为什么您在查询中特别选择$not运算符,为什么不选择$ne?虽然您是正确的,而且您的查询仍然为我提供了正确的答案,但不知何故,我觉得$ne显然应该是正确的运算符。我更新了答案,以解释Mongo处理
$ne
$not
之间的区别。希望有帮助。