Mongodb $unwind空数组
我有一个用户集合,其中每个文档都有以下结构:Mongodb $unwind空数组,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我有一个用户集合,其中每个文档都有以下结构: { "_id": "<id>", "login": "xxx", "solved": [ { "problem": "<problemID>", "points": 10 }, ... ] } 但是,我遇到以下错误: exception: The top-level _id field is the only field currently supported
{
"_id": "<id>",
"login": "xxx",
"solved": [
{
"problem": "<problemID>",
"points": 10
},
...
]
}
但是,我遇到以下错误:
exception: The top-level _id field is the only field currently supported for exclusion
提前感谢这是解决方案-它假设字段“已解决”要么不存在,要么等于null,要么已解决一系列问题和分数。它不处理的情况是“解决”为空数组-尽管这将是一个简单的额外调整,您可以添加
project = {$project : {
"s" : {
"$ifNull" : [
"$solved",
[
{
"points" : 0
}
]
]
},
"login" : 1
}
};
unwind={$unwind:"$s"};
group= { "$group" : {
"_id" : "$_id",
"login" : {
"$first" : "$login"
},
"score" : {
"$sum" : "$s.points"
}
}
}
db.students.aggregate([project,unwind,group])代码>对于MongoDB 3.2版及更新版本,操作符现在有一些选项,特别是preserveNullandEmptyArray
选项将解决此问题
如果此选项设置为true,并且路径为null、缺失或空数组,将输出文档。如果为false,如果路径为null、缺少或为空数组,则不会输出文档。在您的情况下,将其设置为true:
db.collection.aggregate([
{ "$unwind": {
"path": "$solved",
"preserveNullAndEmptyArrays": true
} },
{ "$group": {
"_id": "$_id",
"login": { "$first": "$login" },
"solved": { "$sum": "$solved.points" }
} }
])
当您说“solved may is empty”(已解决可能是空的)时,它是否存在并且是一个空数组,或者在没有解决问题的情况下它是否不存在?另外,$first login获得第一个值(按数组顺序)-这是您想要的,还是想要$min?如果没有问题得到解决,登录名是否也可以为null或缺失?Hello@AsyaKamsky,我已经在MongoDB 3.0.3上尝试了您的代码,但是$ifNull不能完全正常工作?此外,我也无法在上对此问题做任何说明。相反,我使用了's':{$cond:[{$eq:[{$size:'$solved'},0]}、[{point:0}]、'$solved']}
并报告了Jira。编写此答案时,$size不存在,因此我无法在解决方案中使用它。下一个版本(3.2)也将有$isArray操作符。我不知道你所说的$ifNull“完全”不工作是什么意思,所以不能对此发表评论。我的意思是,我认为,$ifNull
的工作方式将类似于文档{$ifNull:[,]}
。但是,它并没有像上面的代码那样替换表达式。你能告诉我有没有其他接线员吗?(因为不再有$size
运算符)我已使用's':{$cond:[{$eq:['$solved',[]},[{point:0}],'$solved']}
解决了这个问题。不管怎样,谢谢你…问得好,回答得好。你救了我一天
db.collection.aggregate([
{ "$unwind": {
"path": "$solved",
"preserveNullAndEmptyArrays": true
} },
{ "$group": {
"_id": "$_id",
"login": { "$first": "$login" },
"solved": { "$sum": "$solved.points" }
} }
])