MongoDB的aggregate的pipeline中,有
$unwind
操作符,该操作符用于延展某一个数组类型的元素,作用与Python中的flatten(拍平)类似。但是在实际使用中,
$unwind
有一个非常明显的问题,
就是如果要unwind的字段为空数组或者不存在时,则不会输出该文档。这样会引发pipeline中的计数有问题或者文档条目数莫名的减少
。
方法一
在MongoDB 3.2和更高版本中,
$unwind
运算符现在具有一些选项,其中特别是preserveNullAndEmptyArrays选项将解决此问题.
如果此选项设置为true,并且路径为空,缺少或为空数组,则
$unwind
输出文档.如果为假,则
$unwind
不会输出文档。路径为空,缺少或为空数组.在您的情况下,将其设置为true:
db.collection.aggregate([
{ "$unwind": {
"path": "$solved",
"preserveNullAndEmptyArrays": true
} },
{ "$group": {
"_id": "$_id",
"login": { "$first": "$login" },
"solved": { "$sum": "$solved.points" }
} }
])
方法二
不使用
$unwind
操作符,如果确定联表后的数组只有一个数组元素,直接在
$
project
使用
$arrayElemAt
操作符根据下标去获取数组中的元素即可。获取不到,对应的字段不会在文档中进行展示,但是会输出该文档。
pipeline = [
{'$lookup': {'foreignField': 'dev_id', 'as': 'dev_info', 'from': 'device_info', 'localField': 'device_id'}},
# {'$unwind': '$dev_info'},
{'$project':
{
'device_type': {"$arrayElemAt": ["$dev_info.dev_type", 0]},
'device_name': {"$arrayElemAt": ["$dev_info.dev_name", 0]}
}
}
]