JAC*_*703 1 mongodb mongodb-query aggregation-framework
我有一些文件存储在MongoDB中,类似于以下内容:
{
"id": "0001",
"name": "Joe",
"last_name": "Blogs",
"results":
[
{ "id": "5001", "mark": "78" },
{ "id": "5002", "mark": "105" },
{ "id": "5005", "mark": "97" },
]
}
Run Code Online (Sandbox Code Playgroud)
有许多类似于上面的条目.我遇到的问题是一些"结果"字段完全丢失,所以有些条目如下所示:
{
"id": "0001",
"name": "Joe",
"last_name": "Blogs"
}
Run Code Online (Sandbox Code Playgroud)
我试图聚合这个以返回"名称","last_name"和平均"标记".我对以下代码表示满意:
db.sites.aggregate(
{ $project : { name : "$name", last_name : "$last_name", results : "$results" } },
{ $unwind: "$results" },
{ $group : {
_id : "$_id",
average_mark : { $avg : "$results.mark" },
name : { $last : "$name" },
last_name : { $last : "$last_name" },
}
)
Run Code Online (Sandbox Code Playgroud)
但是,它不会返回没有"results"数组的条目.
有没有人知道如何返回缺少的"结果"条目并将平均值设置为零?
干杯,
詹姆士.
当聚合框架遇到"空"数组时,结果会$unwind有效地从管道中删除文档,因为它被认为没有结果.此外,如果数组根本不存在,则会产生错误,因为操作员将尝试访问不存在的元素.
因此,如果您不希望从聚合结果中明确"过滤"这些文档,则$ifNull存在运算符.它测试是否存在字段,要么返回该字段,要么返回备用提供的参数.
db.sites.aggregate([
{ "$project": {
"name": 1,
"last_name": 1,
"results" : {
"$ifNull": [ "$results", [{ "mark": 0 }] ]
}
}},
{ "$unwind": "$results" },
{ "$group": {
"_id" : "$_id",
"average_mark": { "$avg": "$results.mark" },
"name": { "$last": "$name" },
"last_name": { "$last": "$last_name" },
}}
])
Run Code Online (Sandbox Code Playgroud)
$cond当您真正拥有"空"阵列时,即使组合使用,操作员也可以获得类似的结果:
"results": {
"$cond": [
{"$eq": [ "$results", [] ] },
[{ "mark": 0 }],
{ "$ifNull": [ "$results", [{ "mark": 0 }] ] }
]
}
Run Code Online (Sandbox Code Playgroud)