BeingSuman
BeingSuman

Reputation: 3323

How to group over Array elements using Mongoose Aggregation FrameWork

I have following Mongoose schemas :

EmployeeSchema :

var EmployeeSchema = new Schema({
    name : String,
    employeeDetailsId: {
        type: Schema.Types.ObjectId,
        ref: 'employeedetails'
    }
});

EmployeeDetailSchema :

var EmployeeDetailSchema = new Schema({
    employeeId: {
        type: Schema.Types.ObjectId,
        ref: 'employee'
    },
    statusId: {
        type: Schema.Types.ObjectId,
        ref: 'status'
    },
    primarySkills: [
    {
        type: Schema.Types.ObjectId,
        ref: 'skills'
    }]
});

SkillsSchema :

var SkillsSchema = new Schema({
    name: {
        type: String,
        required: true
    }
});

Following is the data that's got saved in EmployeeDetails collection :

/* 1 */
{
    "_id" : ObjectId("583fbbfe78854dd424f0523f"),
    "employeeId" : ObjectId("583f114e1cff44b7ab414dc1"),
    "statusId" : ObjectId("583ee05a1d5161941632091a"),
    "secondarySkills" : [],
    "primarySkills" : [],
    "__v" : 0
}

/* 2 */
{
    "_id" : ObjectId("583ff108cfa71d942269b09b"),
    "employeeId" : ObjectId("583f114e1cff44b7ab414dc4"),
    "statusId" : ObjectId("583ee05a1d5161941632091a"),
    "secondarySkills" : [],
    "primarySkills" : [],
    "__v" : 0
}

/* 3 */
{
    "_id" : ObjectId("5848c40599fa37d40a7e7392"),
    "employeeId" : ObjectId("583f114e1cff44b7ab414dc8"),
    "secondarySkills" : [ 
        ObjectId("5838373072d7bab017488ba2")
    ],
    "primarySkills" : [ 
        ObjectId("5848c3c299fa37d40a7e7390"), 
        ObjectId("5848c3d599fa37d40a7e7391")
    ],
    "__v" : 0
}

/* 4 */
{
    "_id" : ObjectId("5848c41699fa37d40a7e7393"),
    "employeeId" : ObjectId("583f114e1cff44b7ab414dc6"),
    "secondarySkills" : [],
    "primarySkills" : [ 
        ObjectId("5838373072d7bab017488ba2"), 
        ObjectId("5848c3c299fa37d40a7e7390"), 
        ObjectId("5848c3d599fa37d40a7e7391")
    ],
    "__v" : 0
}

UseCase :

When i want to group EmployeeDetails collection based on Status ID, i used following aggregation in Mongoose :

EmployeeDetailsModel.aggregate([
        {
            $group: {_id: "$statusId", count: {$sum: 1}}
        }
    ]).exec(...);

In similar way, i want to group based on primarySkills or secondarySkills where both of them are array of Skill ObjectID's.

I tried few approaches but no luck. Need some help.

Upvotes: 2

Views: 3446

Answers (1)

YLS
YLS

Reputation: 717

So if you are trying to get a result that shows a list of employees who has a certain skill, $unwind might help.

db.emp.aggregate([{$unwind:"$primarySkills"},{$group:{"_id":"$primarySkills", "employees":{$push:"$employeeId"}}}])

And here's the result:

{ "_id" : ObjectId("5848c3d599fa37d40a7e7391"), "employees" : [ ObjectId("583f114e1cff44b7ab414dc6"), ObjectId("583f114e1cff44b7ab414dc8") ] }
{ "_id" : ObjectId("5848c3c299fa37d40a7e7390"), "employees" : [ ObjectId("583f114e1cff44b7ab414dc6"), ObjectId("583f114e1cff44b7ab414dc8") ] }
{ "_id" : ObjectId("5838373072d7bab017488ba2"), "employees" : [ ObjectId("583f114e1cff44b7ab414dc6") ] }

The $unwind doc.

Upvotes: 7

Related Questions