【问题标题】:MongoDB grouping task - multiple groups, conditionsMongoDB分组任务-多组,条件
【发布时间】:2017-05-11 02:19:40
【问题描述】:

我的目标是获取属于“课程”的所有“学生”文档 至少有一名“蓝色”学生和至少一名 “红色”级。

我倾向于在 Python (pymongo) 中简单地执行一系列查询,直接处理任务。

我想知道是否有一些我可以使用的聪明的聚合管道!

给定:

类集合:

{ class_id: 'a' }
{ class_id: 'b' }

学生合集:

{ class_id: 'a',
grade: 'blue' }

{class_id: 'a',
grade: 'red' }

【问题讨论】:

    标签: mongodb aggregation-framework pymongo


    【解决方案1】:

    你可以使用:

    • a $groupclass_id$push 分组在一个数组中,这样我们就可以在下一步轻松推断出哪个类“包含”blue。使用$$ROOT 保留当前文档,因为我们需要与class_id 匹配的学生

    • $match 仅匹配其中包含等级 blue 的课程

    • $unwind 删除之前的$$ROOT 生成的学生数组

    • $project 可以很好地重新组织您的文档

    查询将是:

    db.students.aggregate([{
        "$group": {
            "_id": "$class_id",
            "grades": { "$push": "$grade" },
            "students": { "$push": "$$ROOT" }
        }
    }, {
        "$match": {
            "grades": { "$all": ["blue","red"] }
        }
    }, {
        "$unwind": "$students"
    }, {
        "$project": {
            "_id": "$students._id",
            "class_id": "$students.class_id",
            "grade": "$students.grade",
        }
    }])
    

    如果您需要匹配 ["blue","re​​d"] 以外的其他颜色,您可以在 $match 聚合中添加更多颜色 ($in: ["blue","red","yellow"])

    在 PyMongo 中实现它非常简单:

    from pymongo import MongoClient
    import pprint
    
    db = MongoClient().testDB
    
    pipeline = [ <the_aggregation_query_here> ]
    
    pprint.pprint(list(db.students.aggregate(pipeline)))
    

    另外,要仅匹配属于 classes 集合的学生,请执行 $lookup 并匹配那些不为空的学生。在聚合查询中添加以下内容:

    {
        $lookup: {
            from: "classes",
            localField: "class_id",
            foreignField: "class_id",
            as: "class"
        }
    }, {
        $match: {
            "class": { $not: { $size: 0 } }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-31
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      • 2022-11-23
      • 2019-02-11
      • 2023-01-17
      • 1970-01-01
      相关资源
      最近更新 更多