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
之间的区别。希望有帮助。