我有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
只是为每个错误添加了用户名。所以我得到一个名字重复的数组。
答案 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
。