如何使用groupby获取group在mongoDB中获取具有动态状态的结果

时间:2018-08-04 08:35:47

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

我有如下收藏

{
    "_id" : ObjectId("5b6538704ba0292b6c197770"),
    "Name":"Name1",
    "Status":"Good",


},
{
    "_id" : ObjectId("5b6538704ba0292b6c197773"),
     "Name":"Name2",
    "Status":"Bad"
},
{
    "_id" : ObjectId("5b6538704ba0292b6c197774"),
    "Name":"Name3",
    "Status":"Bad"
},{
    "_id" : ObjectId("5b6538704ba0292b6c197774"),
    "Name":"Name1",
    "Status":"Bad"
},
{
    "_id" : ObjectId("5b6538704ba0292b6c197775"),
     "Name":"Name1",
    "Status":"Good"
}

我已经使用查询来获取如下状态明智计数

db.Students.aggregate( [

  { $group: {   _id:  { 
            "Name": "$Name","Status":"$Status"}, StatusCount: { $sum: 1 } } }  
        ,  { "$project": { _id: 0, Name: "$_id.Name",Status : "$_id.Status", StatusCount:1 } }
] );

结果是

{
    "Name":"Name1",
    "StatusCount" : 2,
    "Status" : "Good"

},
{
    "Name":"Name2",
    "StatusCount" : 1,
    "Status" : "Bad"       
}, {
    "Name":"Name2",
    "StatusCount" : 1,
    "Status" : "Bad"       
}, 
{
    "Name":"Name1",
    "StatusCount" : 1,
    "Status" : "Bad"       
}

我要处理的结果是

   {
        "Name":"Name1",
        "Good" : 2,
        "Bad"   :1        
    },
{
        "Name":"Name2",
        "Good" : 0,
        "Bad"   :1  
}

我希望结果具有字段名称的状态并将其计为值。我曾尝试这样做,但我无法实现。目前,状态只有“好”或“不好”两种,但在实际数据集中可能会增加。

1 个答案:

答案 0 :(得分:1)

使用 $arrayToObject 运算符和最后的 $replaceRoot 管道步骤,该步骤具有 $mergeObjects 运算符,您会得到想要的结果。

您需要在MongoDB Server 3.4.4或更高版本上运行以下聚合管道:

const pipeline = [
    { '$group': {
        '_id': {
            'Name': '$Name',
            'Status': '$Status'
        },
        'StatusCount': { '$sum': 1 }
    } },
    { '$group': {
        '_id': '$_id.Name',
        'counts': {
            '$push': {
                'k': '$_id.Status',
                'v': '$StatusCount'
            }
        }
    } },
    {  '$replaceRoot': {
        'newRoot': { '$mergeObjects': [ 
            { '$arrayToObject': '$counts' }, 
            { 'Name': '$_id' } 
        ] }
    } } 
];

db.Students.aggregate(pipeline);