如何在对象数组中没有确切对象的条件下搜索文档? [英] How to search document with condition of not having exact object in array of objects?
问题描述
我有一个人的集合,其架构看起来像以下文档的集合.
I have a collection of persons whose schema looks like the collection of following documents.
Document: {
name:
age:
educations:[{
title:xyz,
passed_year:2005,
univercity:abc},
{
title:asd
passed_year:2007,
univercity:mno
}],
current_city:ghi
}
现在我想展示所有没有在 2005 年从 abc 大学接受过 xyz 教育的人.
Now I wanna show all the persons who has not done xyz education from abc university in year 2005.
我认为有两种可能的查询来满足这种需求,但不确定使用哪一种,因为它们都给了我输出
I think two possible queries for this need but not sure which one to use as both of them are giving me the output
查询 1:
db.persons.find({"education":{$ne:{$elemMatch:{"title":"xyz","passed_year":2005,"univercity":"abc"}}}})
db.persons.find({"education":{$ne:{$elemMatch:{"title":"xyz","passed_year":2005,"univercity":"abc"}}}})
查询 2:
db.persons.find({"education":{$not:{$elemMatch:{"title":"xyz","passed_year":2005,"univercity":"abc"}}}})
db.persons.find({"education":{$not:{$elemMatch:{"title":"xyz","passed_year":2005,"univercity":"abc"}}}})
我对运算符 $ne 和 $not 感到很困惑,我应该将哪个与 $elemMatch 一起使用,因为它们都给我输出.
I'm quite confused about operator $ne and $not, which one should I use with $elemMatch as both of them are giving me the output.
推荐答案
鉴于此 $elemMatch
: {"title":"xyz","passed_year":2005,"univercity":"abc"}
我认为您想排除包含所有这些对的教育数组中包含子文档的任何文档:
Given this $elemMatch
: {"title":"xyz","passed_year":2005,"univercity":"abc"}
I think you want to exclude any documents which contain an sub document in the educations array which contains all of these pairs:
- "title" : "xyz"
- "passed_year" : 2005
- "univercity" : "abc"
此查询将实现:
db.persons.find({
"educations": {
$not: {
$elemMatch:{"title": "xyz", "passed_year": 2005, "univercity": "abc"}
}
}
})
在你的问题中你写道:
他们都给了我输出
我怀疑这是因为您的查询指定了 education
而正确的属性名称是 educations
.通过指定 education
,您将添加一个无法评估的谓词,因为它引用了一个不存在的文档属性,因此无论该谓词是使用 $ne
还是 $not
它不会被应用.
I suspect this is because your query is specifying education
whereas the correct attribute name is educations
. By specifying education
you are adding a predicate which cannot be evaluated since it references a non existent document attribute so regardless of whether that predicate uses $ne
or $not
it will simply not be applied.
回答使用哪个运算符的问题:$not
或 $ne
:如果您使用 .explain(true)<运行上述查询/code> 您会注意到 Mongo 生成的解析查询对于这些运算符中的每一个都非常不同.
In answer to the question of which operator to use: $not
or $ne
: if you run the above query with .explain(true)
you'll notice that the parsed query produced by Mongo is very different for each of these operators.
使用
$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 执行类似此伪代码的操作...
So, it looks like use of $ne
causes Mongo to do something like this psuedo code ...
not educations equalTo "$elemMatch" : {"title" : "xyz", "passed_year" : 2005, "univercity" : "abc"}
... 即它将 elemMatch 子句视为等式运算的 RHS,而使用 $not
会导致 Mongo 实际评估 elemMatch 子句.
... i.e. it treats the elemMatch clause as if it is the RHS of an equality operation whereas use of $not
causes Mongo to actually evaluate the elemMatch clause.
这篇关于如何在对象数组中没有确切对象的条件下搜索文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!