She*_*lef 7 mongodb aggregation-framework
我需要创建在具有相似结构的多个集合上运行的聚合。我知道$lookup aggregation,但实际上我不想在文档之间加入,而是列出所有集合中的所有文档。为了更好地阐明我的意图,我将使用一个例子。
学生作品集:
{
"_id" : ObjectId("57278a449fb5ba91248b3bc0"),
"age": 22
}
Run Code Online (Sandbox Code Playgroud)
教师作品集:
{
"_id" : ObjectId("57278a449fb5ba91248b3bc0"),
"age": 28
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个聚合,该聚合将给出两个集合的平均年龄。如何在不使用两个聚合的情况下将结果与我的代码结合起来?
您可以使用新的管道样式查找,如下所示:
db.getCollection('students').aggregate(
[
{
$group: {
'_id': 0
}
},
{
$lookup: {
from: 'students',
let: {},
pipeline: [
{ $group: {
'_id': 0,
'avg': { $avg: '$age' },
'count': { $sum: 1 }
} }
],
as: 'students'
}
},
{
$lookup: {
from: 'teachers',
let: {},
pipeline: [
{ $group: {
'_id': 0,
'avg': { $avg: '$age' },
'count': { $sum: 1 }
} }
],
as: 'teachers'
}
},
{
$unwind: {
path : '$students',
}
},
{
$unwind: {
path : '$teachers',
}
},
{
$project: {
'avg_age': { $divide: [
{ $sum: [
{ $multiply: [ '$students.avg', '$students.count' ] },
{ $multiply: [ '$teachers.avg', '$teachers.count' ] }
] },
{ $sum: [ '$students.count', '$teachers.count' ] },
] }
}
},
]
);
Run Code Online (Sandbox Code Playgroud)
第一$group阶段为您提供单个空文档作为开始,因此每个阶段$lookup仅执行一次。您可以通过按计数加权来合并每个集合的平均值,这会得到与对所有文档求平均值相同的结果。