多个集合上的 MongoDB 聚合

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)

我想创建一个聚合,该聚合将给出两个集合的平均年龄。如何在不使用两个聚合的情况下将结果与我的代码结合起来?

Sam*_*may 5

您可以使用新的管道样式查找,如下所示:

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仅执行一次。您可以通过按计数加权来合并每个集合的平均值,这会得到与对所有文档求平均值相同的结果。