MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Requête d'agrégation MongoDb avec $group et $push into subdocument

Essayez d'exécuter le pipeline d'agrégation suivant, la clé utilise un dernier $project pipeline pour créer le attendeeContainer sous-document :

db.event.aggregate([
    { "$unwind": "$attendeeContainer.attendees" },
    {
        "$lookup" : { 
            "from" : "contactinfo", 
            "localField" : "attendeeContainer.attendees.contact",
            "foreignField" : "_id", 
            "as" : "attendeeContainer.attendees.contactInfo" 
        }
    },
    { "$unwind": "$attendeeContainer.attendees.contactInfo" },
    {
        "$group": {
            "_id" : "$_id",
            "name": { "$first": "$name" },   
            "min" : { "$first": "$attendeeContainer.min" },
            "max" : { "$first": "$attendeeContainer.max" },
            "attendees": { "$push": "$attendeeContainer.attendees" }            
        }
    },
    {
        "$project": {
            "name": 1,
            "attendeeContainer.min": "$min",
            "attendeeContainer.max": "$min",
            "attendeeContainer.attendees": "$attendees"
        }
    }
])

Conseils de débogage

En déboguant le pipeline à la 4ème étape, vous obtiendriez le résultat

db.event.aggregate([
    { "$unwind": "$attendeeContainer.attendees" },
    {
        "$lookup" : { 
            "from" : "contactinfo", 
            "localField" : "attendeeContainer.attendees.contact",
            "foreignField" : "_id", 
            "as" : "attendeeContainer.attendees.contactInfo" 
        }
    },
    { "$unwind": "$attendeeContainer.attendees.contactInfo" },
    {
        "$group": {
            "_id": "$_id",
            "name": { "$first": "$name" },   
            "min" : { "$first": "$attendeeContainer.min" },
            "max" : { "$first": "$attendeeContainer.max" },
            "attendees": { "$push": "$attendeeContainer.attendees" }            
        }
    }/*,
    {
        "$project": {
            "name": 1,
            "attendeeContainer.min": "$min",
            "attendeeContainer.max": "$min",
            "attendeeContainer.attendees": "$attendees"
        }
    }*/
])

Résultat du pipeline

{
    "_id" : ObjectId("582c789282a9183adc0b53f5"),
    "name" : "Some Event",
    "min" : 0,
    "max" : 10,
    "attendees" : [ 
        {
            "type" : 1,
            "status" : 2,
            "contact" : ObjectId("582c787682a9183adc0b53f3"),
            "contactInfo" : {
                "_id" : ObjectId("582c787682a9183adc0b53f3"),
                "name" : "John Doe",
                "age" : 35
            }
        }, 
        {
            "type" : 7,
            "status" : 4,
            "contact" : ObjectId("582c787682a9183adc0b53f4"),
            "contactInfo" : {
                "_id" : ObjectId("582c787682a9183adc0b53f4"),
                "name" : "Peter Pan",
                "age" : 60
            }
        }
    ]
}

et le dernier $project pipeline vous donnera le résultat souhaité :

db.event.aggregate([
    { "$unwind": "$attendeeContainer.attendees" },
    {
        "$lookup" : { 
            "from" : "contactinfo", 
            "localField" : "attendeeContainer.attendees.contact",
            "foreignField" : "_id", 
            "as" : "attendeeContainer.attendees.contactInfo" 
        }
    },
    { "$unwind": "$attendeeContainer.attendees.contactInfo" },
    {
        "$group": {
            "_id": "$_id",
            "name": { "$first": "$name" },   
            "min" : { "$first": "$attendeeContainer.min" },
            "max" : { "$first": "$attendeeContainer.max" },
            "attendees": { "$push": "$attendeeContainer.attendees" }            
        }
    },
    {
        "$project": {
            "name": 1,
            "attendeeContainer.min": "$min",
            "attendeeContainer.max": "$min",
            "attendeeContainer.attendees": "$attendees"
        }
    }/**/
])

Sortie souhaitée/réelle

{
    "_id" : ObjectId("582c789282a9183adc0b53f5"),
    "name" : "Some Event",
    "attendeeContainer" : {
        "min" : 0,
        "max" : 10,
        "attendees" : [ 
            {
                "type" : 1,
                "status" : 2,
                "contact" : ObjectId("582c787682a9183adc0b53f3"),
                "contactInfo" : {
                    "_id" : ObjectId("582c787682a9183adc0b53f3"),
                    "name" : "John Doe",
                    "age" : 35
                }
            }, 
            {
                "type" : 7,
                "status" : 4,
                "contact" : ObjectId("582c787682a9183adc0b53f4"),
                "contactInfo" : {
                    "_id" : ObjectId("582c787682a9183adc0b53f4"),
                    "name" : "Peter Pan",
                    "age" : 60
                }
            }
        ]
    }
}