【问题标题】:MongoDB aggregation on multiple collections多个集合上的 MongoDB 聚合
【发布时间】:2017-03-29 11:08:08
【问题描述】:

我需要创建在具有相似结构的多个集合上运行的聚合。我知道$lookup aggregation,但实际上我不想加入文档之间,而是要列出所有集合中的所有文档。为了更好地阐明我的意图,我将使用一个示例。

学生合集:

{
     "_id" : ObjectId("57278a449fb5ba91248b3bc0"),
     "age": 22
}

教师合集:

{
     "_id" : ObjectId("57278a449fb5ba91248b3bc0"),
     "age": 28
}

我想创建一个聚合,它可以为我提供两个集合的平均年龄。如何在不使用两个聚合并将结果与​​我的代码结合的情况下做到这一点?

【问题讨论】:

  • 这是不可能的,您必须在 2 个单独的查询中执行此操作
  • 如果您检查聚合语法,则不可能: Model.aggregrate 。这意味着您正在对特定模型进行聚合
  • @Sam 如果您指定 Model 那么这是 mongoose 语法,而不是 mongodb 本机。
  • 我在考虑 $lookup 和 $unwind 的组合,是否可以将一个集合插入到一个文档网络的列表中,而不是将其展开到单独的文档中?

标签: mongodb aggregation-framework


【解决方案1】:

您可以像这样使用新的管道样式查找:

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' ] },
                ] }
            }
        },
    ]
);

第一个$group 阶段为您提供了一个空文档,因此每个$lookup 只执行一次。您可以通过按计数加权来组合每个集合的平均值,这与对所有文档取平均值的结果相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-06
    • 2020-02-16
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 2014-05-27
    • 2014-09-29
    • 2013-06-17
    相关资源
    最近更新 更多