每月按用户更正分组查询

时间:2014-06-30 08:54:17

标签: mongodb mongodb-query aggregation-framework

我有MongoDB集合,以这种格式存储文档:

"name" : "Username",
"timeOfError" : ISODate("...")

我正在使用此集合来跟踪谁收到错误以及何时发生错误。

我现在要做的是创建一个查询,检索每个用户,每月或类似的错误。像这样:

{
"result": [
    {
        "_id": "$name",
        "errorsPerMonth": [
            {
                "month": "0",
                "errorsThisMonth": 10
            },
            {
                "month": "1",
                "errorsThisMonth": 20
            }
        ]
     }
   ]
}

我尝试了几种不同的查询,但都没有给出所需的结果。最接近的结果来自此查询:

db.collection.aggregate(
                  [
                    { 
                        $group: 
                        {
                            _id: { $month: "$timeOfError"},
                            name: { $push: "$name" },
                            totalErrorsThisMonth: { $sum: 1 }
                        } 
                    }
                  ] 
);

这里的问题是$push只是为每个错误添加了用户名。所以我得到一个名字重复的数组。

1 个答案:

答案 0 :(得分:1)

您需要在$group中复合_id值:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "name": "$name",
            "month": { "$month": "$timeOfError" }
        },
        "totalErrors": { "$sum": 1 }
    }}
])

_id本质上是“分组键”,因此您想要分组的任何元素都需要成为其中的一部分。

如果您想要不同的订单,则可以更改分组键优先级:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "month": { "$month": "$timeOfError" },
            "name": "$name"
        },
        "totalErrors": { "$sum": 1 }
    }}
])

或者,如果您想要在管道中使用不同字段或在其他条件中使用其他条件,则只需在末尾添加$sort管道阶段:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "month": { "$month": "$timeOfError" },
            "name": "$name"
        },
        "totalErrors": { "$sum": 1 }
    }},
    { "$sort": { "_id.name": 1, "_id.month": 1 } }
])

你可以在任何你想要的地方$sort