使用$ group聚合两次

时间:2017-02-05 10:44:07

标签: mongodb mongodb-query aggregation-framework

我已经阅读了SO和这样的问题one。但是我无法构建我想要的查询...

假设我有以下数据结构:

{ 
    "CAUG" : "id1", 
    "action" : "actionA", 
    "date" : ISODate("2017-01-01"), 
    "hp" : 16
}
{ 
    "CAUG" : "id1", 
    "action" : "actionB", 
    "date" : ISODate("2017-01-01"), 
    "hp" : 17
}
{ 
    "CAUG" : "id1", 
    "action" : "actionC", 
    "date" : ISODate("2017-02-10"), 
    "hp" : 18
}
{ 
    "CAUG" : "id2", 
    "action" : "actionX", 
    "date" : ISODate("2018-01-01"), 
    "hp" : 20
}...

所需的输出类似于(不确定括号和其他东西......):

{ 
    "CAUG" : "id1", 
    "timeline" : [
        ISODate ("2017-01-01) {
            { "action" : "ActionA", hp : "..." }
            { "action" : "ActionB", hp : "..." }
        },
        ISODate ("2017-02-10) {
            { "action" : "ActionC", hp : "..." }
        }
    ]
}
{ 
    "CAUG" : "id2", 
    "timeline" : [
        ISODate ("2018-01-01) {
            { "action" : "ActionX", hp : "..." }
        }
    ]
}

此时我的(非常有限的)查询是:

(我尝试了很多像复合_id这样的东西,但我总是在某些方面受到限制。)

db.aggregate(
    [
        { $match: { something } },
        { $project: { something } },
        { $group: {
              _id: '$CAUG',
              "timeline": { "$push": "$$ROOT"  }
            }
        }
    ]
)

问题是我不知道如何在$group数组内做另一个timeline ...我对下面的输出感到困惑...有任何线索吗?祝周末愉快。

{ 
    "_id" : "1", 
    "timeline" : [
        {
            "CAUG" : "ca220491-ug43816", 
            "action" : "actionA", 
            "date" : ISODate("2016-12-21T23:00:00.000+0000")
        }, 
        {
            "CAUG" : "ca220491-ug43816", 
            "action" : "actionB", 
            "date" : ISODate("2016-12-21T23:00:00.000+0000")
        }, 
        {
            "CAUG" : "ca220491-ug43816", 
            "action" : "actionC", 
            "date" : ISODate("2017-02-21T23:00:00.000+0000")
        }
    ]
}

1 个答案:

答案 0 :(得分:1)

尝试运行以下聚合操作:

db.collection.aggregate([
    {
        "$group": {
            "_id": {
                "CAUG": "$CAUG",
                "date": {
                    "$dateToString": {
                        "format": "%Y-%m-%d", 
                        "date": "$date"
                    }
                }
            },
            "docs": {
                "$push": {
                    "action" : "$action",
                    "hp" : "$hp"
                }
            }                
        }
    },
    {
        "$group": {
            "_id": "$_id.CAUG",
            "timeline": {
                "$push": {
                    "date": "$_id.date",
                    "docs": "$docs"
                }
            }
        }
    }
])

给出样本输出

/* 1 */
{
    "_id" : "id1",
    "timeline" : [ 
        {
            "date" : "2017-02-10",
            "docs" : [ 
                {
                    "action" : "actionC",
                    "hp" : 18.0
                }
            ]
        }, 
        {
            "date" : "2017-01-01",
            "docs" : [ 
                {
                    "action" : "actionA",
                    "hp" : 16.0
                }, 
                {
                    "action" : "actionB",
                    "hp" : 17.0
                }
            ]
        }
    ]
}

/* 2 */
{
    "_id" : "id2",
    "timeline" : [ 
        {
            "date" : "2018-01-01",
            "docs" : [ 
                {
                    "action" : "actionX",
                    "hp" : 20.0
                }
            ]
        }
    ]
}