从复杂模型中选择所有对象

时间:2014-09-18 18:00:27

标签: mongodb mongodb-query aggregation-framework

我有聚合管道阶段:

$project: {
    'school': {
        'id': '$_id',
        'name': '$name',
        'manager': '$manager'
    },
    'students': '$groups.students',
    'teachers': '$groups.teachers'
}

需要这样的东西:

{
    'users': // manager + students + teachers
}

尝试:

{
    'users': {
        $push: {
            $each: ['$school.manager', '$students', '$teachers']
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我认为"学生"和#34;老师"这两个数组都位于一个共同的子文档标题下,如下所示:

{
    "_id": 123,
    "name": "This school",
    "manager": "Bill"
    "groups": {
        "teachers": ["Ted"],
        "students": ["Missy"]
    }
}

所以为了得到所有这些,如#34;用户"那么它取决于你的MongoDB版本和"唯一性"你的数据。对于真正的"套"如果你有MongoDB 2.6或更高版本,那么就有$setUnion运营商,虽然有$group的额外等级来制作"经理"和数组:

db.collection.aggregate([
    { "$group": {
        "_id": { "_id": "$_id", "name": "$name" },
        "manager": { "$push": "$manager" },
        "groups": { "$first": "$groups" }
    }},
    { "$project": {
        "users": { 
            "$setUnion": [ "$manager", "$groups.teachers", "$groups.students" ]
        }
    }}
])

或者其他地方没有该运营商或者有一个"唯一的"问题是有这种方式处理"结合":

db.collection.aggregate([
    { "$group": {
        "_id": { "_id": "_id", "name": "$name" },
        "manager": { "$push": "$manager" },
        "teachers": { "$first": "$groups.teachers" },
        "students": { "$first": "$groups.students" },
        "type": { "$first": { "$const": ["M","T","S"] } }
    }},
    { "$unwind": "$type" },
    { "$project": {
        "users": {
            "$cond": [
                { "$eq": [ "$type", "M" ] },
                "$manager",
                { "$cond": [
                    { "$eq": [ "$type", "T" ] },
                    "$teachers",
                    "$students"
                ]}
             ]
        }
    }},
    { "$unwind": "$users" },
    { "$group": {
        "_id": "$_id",
        "users": { "$push": "$users" }
    }}
])

这基本上是#34;标签"每个字段由"类型"将文档复制到管道中。然后放入单个"用户"字段取决于"类型"匹配。然后,从每个原件得到的三个文件中的单个阵列可以安全地解开"并在最终的$group操作中合并。

所以"设置"是最快的选择,如果可用或不可用或不唯一,您可以使用后面的技术将它们组合到一个列表中。