MongoDB - 使用$ group在$ lookup后重绕$ unwind嵌套数组

Sun*_*Lee 11 join mongodb mongodb-query aggregation-framework mongodb-aggregation

MongoDB聚合按分钟呈指数级复杂化!

我在迄今为$unwind嵌套数组,然后执行$lookup_id每一个对象的从unwinded嵌套数组.我的最后一次尝试是逆转放松$group.但是,我无法使用其原始属性名称以及每个文档的其余原始直接属性重建原始嵌入数组.

这是我到目前为止的尝试:

db.users.aggregate([
    {
        $unwind: "$profile",
        $unwind: {
            path: "$profile.universities",
            preserveNullAndEmptyArrays: true
        }
    },
    {
        $lookup: {
            from: "universities",
            localField: "profile.universities._id",
            foreignField: "_id",
            as: "profile.universities"
        }
    },
    {
        $group: {
            _id: "$_id",
            emails: { "$first": "$emails" },
            profile: { "$first": "$profile" },
            universities: { "$push": "$profile.universities" }
        }
    }
]).pretty()
Run Code Online (Sandbox Code Playgroud)

我得到的是这样的:

{
    "_id" : "A_USER_ID",
    "emails" : [
        {
            "address" : "AN_EMAIL_ADDRESS",
            "verified" : false
        }
    ],
    "profile" : {
        "name" : "NAME",
        "company" : "A COMPANY",
        "title" : "A TITLE",
        "phone" : "123-123-1234",
        "disabled" : false,
        "universities" : [
            {
                "_id" : "ID_1",
                "name" : "UNIVERSITY_NAME_1",
                "code" : "CODE_1",
                "styles" : {AN_OBJECT}
            }
        ]
    },
    "universities" : [
        [
            {
                "_id" : "ID_1",
                "name" : "UNIVERSITY_NAME_1",
                "code" : "CODE_1",
                "styles" : {AN_OBJECT}
            }
        ],
        [
            {
                "_id" : "ID_2",
                "name" : "UNIVERSITY_NAME_2",
                "code" : "CODE_2",
                "styles" : {AN_OBJECT}
            }
        ]
    ]
}
Run Code Online (Sandbox Code Playgroud)

这个结果有2个问题:

  1. 结果universities是每个对象的数组数组,因为$lookup返回了原始$profile.universities嵌套数组的单个元素数组.它应该只是一个对象数组.
  2. 结果universities应该将其原始位置嵌套在下面profiles.我知道原来profile.universities是这样的,因为我正在使用$first运算符.我的意图是保留profile原始嵌套universities数组的所有原始属性.

最终,我需要的是这样的事情:

{
    "_id" : "A_USER_ID",
    "emails" : [
        {
            "address" : "AN_EMAIL_ADDRESS",
            "verified" : false
        }
    ],
    "profile" : {
        "name" : "NAME",
        "company" : "A COMPANY",
        "title" : "A TITLE",
        "phone" : "123-123-1234",
        "disabled" : false,
        "universities" : [
            {
                "_id" : "ID_1",
                "name" : "UNIVERSITY_NAME_1",
                "code" : "CODE_1",
                "styles" : {AN_OBJECT}
            },
            {
                "_id" : "ID_2",
                "name" : "UNIVERSITY_NAME_2",
                "code" : "CODE_2",
                "styles" : {AN_OBJECT}
            }
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

是否有其他操作员可以使用而不是$group实现此目的?或者我是否理解$group错误的目的?

编辑:这是原始帖子,对于上下文: 如果Mongo $ lookup是左外连接,那么为什么它会排除不匹配的文档?

chr*_*dam 22

由于$lookup运算符生成数组字段,因此需要$unwind$group管道之前使用新字段以获得所需的结果:

db.users.aggregate([
    { "$unwind": "$profile" },
    { "$unwind": {
        "path": "$profile.universities",
         "preserveNullAndEmptyArrays": true
    } }, 
    { "$lookup": {
        "from": "universities",
        "localField": "profile.universities._id",
        "foreignField": "_id",
        "as": "universities"
    } },    
    { "$unwind": "$universities" },
    { "$group": {
        "_id": "$_id",
        "emails": { "$first": "$emails" },
        "profile": { "$first": "$profile" },
        "universities": { "$push": "$universities" }
    } },
    { "$project": {
        "emails": 1,  
        "profile.name" : 1,
        "profile.company": 1,
        "profile.title" : 1,
        "profile.phone" : 1,
        "profile.disabled": 1,          
        "profile.universities": "$universities"
    } }
]).pretty()
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@chridam,第二个`$ unwind`和`$ project`就行了!我必须修改两个部分:1.将第二个展开更改为"$ unwind":{"path":"$ profile.universities","preserveNullAndEmptyArrays":true}`,并且2.更改`$ group`"大学"到""大学":{"$ push":"$ profile.universities"}`我能够得到我的结果. (3认同)