如何使用Mongoose Aggregation FrameWork对Array元素进行分组

时间:2016-12-09 05:12:11

标签: node.js mongodb mongoose mongodb-query aggregation-framework

我有以下Mongoose模式:

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
    }
});

以下是 EmployeeDetails 集合中保存的数据:

/* 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:

当我想根据状态ID对EmployeeDetails集合进行分组时,我在Mongoose中使用了以下聚合:

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

以类似的方式,我想基于primarySkills或secondarySkills进行分组,其中两者都是Skill ObjectID的数组。

我尝试了几种方法,但没有运气。需要一些帮助。

1 个答案:

答案 0 :(得分:4)

因此,如果您试图获得显示具有特定技能的员工列表的结果,那么$ unwind可能会有所帮助。

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

这是结果:

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

$unwind doc