Search code examples
javascriptmongodbmongooseaggregation-frameworkmongoose-schema

MongoDB aggregate with two model


I have two collections, class collection and student collection

class collection
{
    "_id" : "1999558581",
    "name" : "Class One",
},
{
    "_id" : "1999558582",
    "name" : "Class Two",
},
{
    "_id" : "1999558583",
    "name" : "Class Three",
}

and

student collection
{
    "_id" : "111111",
    "First name" : "",
    "Last name" : "",
    "gender" : "Male",
    "class" : "1999558581", //classObjectId
},
{
    "_id" : "111112",
    "First name" : "",
    "Last name" : "",
    "gender" : "Female",
    "class" : "1999558581", //classObjectId
},
{
    "_id" : "111113",
    "First name" : "",
    "Last name" : "",
    "gender" : "Male",
    "class" : "1999558582", //classObjectId
},
{
    "_id" : "111114",
    "First name" : "",
    "Last name" : "",
    "gender" : "Male",
    "class" : "1999558583", //classObjectId
},
{
    "_id" : "111115",
    "First name" : "",
    "Last name" : "",
    "gender" : "Female",
    "class" : "1999558581", //classObjectId
}

I want to get the aggregate by gender in a class and get the name in the class collection.

#This is what I have tried

 const male = await models.Student.aggregate([
        { $match: { gender: "Male" } },
        { $group: { _id: "$class", count: { $sum: 1 } } },
    ]).exec();

#Produce this

             [
                {
                    "_id": "60703f09961728430c9656d1",
                    "count": 9
                },
                {
                    "_id": "60703f09961728430c",
                    "count": 4
                },
                 {
                    "_id": "60703f08430c9656d1",
                    "count": 13
                },
            ]

This "_id": "60703f09961728430c9656d1", is the Id from the class collection, so I want to get the name associated with this _id

               [
                {
                    "_id": "60703f09961728430c9656d1",
                     "name" : "Class One"
                    "count": 9
                },
                {
                    "_id": "60703f09961728430c",
                    "name" : "Class Two"
                    "count": 4
                },
                 {
                    "_id": "60703f08430c9656d1",
                    "name" : "Class Three"
                    "count": 13,
    
                },
            ]


Solution

  • You can use $group and $lookup together and this may solve your problem.

    const male = await models.Student.aggregate([
            { $match: { gender: "Male" } },
            { $group: { _id: "$class", count: { $sum: 1 } } },
            { $lookup: { from: "class", localField: "_id", foreignField: "_id", as: "class"}
        ]).exec()