我有一些文档存储在MongoDB中,类似于以下内容:
{
"id": "0001",
"name": "Joe",
"last_name": "Blogs",
"results":
[
{ "id": "5001", "mark": "78" },
{ "id": "5002", "mark": "105" },
{ "id": "5005", "mark": "97" },
]
}
有许多与上述类似的条目。我遇到的问题是某些“结果”字段完全丢失,因此有些条目如下所示:
{
"id": "0001",
"name": "Joe",
"last_name": "Blogs"
}
我正在尝试聚合它以返回“name”,“last_name”和平均“mark”。我在下面的代码中表现得很好:
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" },
}
)
但是,它不会返回没有“results”数组的条目。
有没有人知道如何返回丢失的“结果”条目并将平均值设置为零?
干杯,
詹姆斯。
答案 0 :(得分:5)
当聚合框架遇到“空”数组时,$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" },
}}
])
当您真正拥有“空”数组时,使用$cond
运算符可以实现类似的结果,甚至可以组合使用:
"results": {
"$cond": [
{"$eq": [ "$results", [] ] },
[{ "mark": 0 }],
{ "$ifNull": [ "$results", [{ "mark": 0 }] ] }
]
}