我在MongoDB中有一个集合,其样本数据类似于此(简化):
{
_id: 1,
username: "ted",
content: "4125151",
status: "complete"
}
{
_id: 2,
username: "sam",
content: "4151",
status: "new"
}
{
_id: 3,
username: "ted",
content: "511",
status: "new"
}
{
_id: 4,
username: "ted",
content: "411",
status: "in_progress"
}
{
_id: 5,
username: "pat",
content: "1sds51",
status: "complete"
}
{
_id: 6,
username: "ted",
content: "4151",
status: "in_progress"
}
{
_id: 7,
username: "ted",
content: "4125",
status: "in_progress"
}
我需要聚合数据,以便为每个用户提供每个状态值的计数以及记录总数。结果应如下所示:
[
{
username: “pat”,
new: 0,
in_progress: 0,
complete: 1,
total: 1
},
{
username: “sam”,
new: 1,
in_progress: 0,
complete: 0,
total: 1
},
{
username: “ted”,
new: 1,
in_progress: 3,
complete: 1,
total: 5
}
]
或任何有效用于同一目的的格式,我希望能够使用ngRepeat以这种格式在前端显示:
User New In Progress Complete Total
pat 0 0 1 1
sam 1 0 0 1
ted 1 3 1 5
我可以执行此聚合:
{
"$group": {
"_id": {
"username": "$username",
"status": "$status"
},
"count": {
"$sum": 1
}
}
}
这为我提供了至少有一条记录的每个用户/状态组合的个人计数。但是我必须将它拼凑在一起才能以我可以在前端使用的格式获得它。这根本不是理想的。
有没有办法执行聚合以获取我需要的格式的数据?
答案 0 :(得分:2)
您想要的是值的“条件”聚合,以便为每个状态生成不同的字段属性。
使用$cond
运算符非常简单:
[
{ "$group": {
"_id": "$username",
"new": { "$sum": { "$cond": [{ "$eq": [ "$status", "new" ] },1,0 ] } },
"complete": { "$sum": { "$cond": [{ "$eq": [ "$status", "complete" ] },1,0 ] } },
"in_progress": { "$sum": { "$cond": [{ "$eq": [ "$status", "in_progress" ] },1,0 ] } },
"total": { "$sum": 1 }
}}
]
当然假设这些是唯一的“状态”值,但如果它们不是,那么只需添加一个$project
来对所需的字段求和:
[
{ "$match": { "status": { "$in": [ "new", "complete", "in_progress" ] } } },
{ "$group": {
"_id": "$username",
"new": { "$sum": { "$cond": [{ "$eq": [ "$status", "new" ] },1,0 ] } },
"complete": { "$sum": { "$cond": [{ "$eq": [ "$status", "complete" ] },1,0 ] } },
"in_progress": { "$sum": { "$cond": [{ "$eq": [ "$status", "in_progress" ] },1,0 ] } }
}},
{ "$project": {
"new": 1,
"complete": 1,
"in_progress": 1,
"total": { "$add": [ "$new", "$complete", "$in_progress" ] }
]
或者只是在$add
中包含$group
,并对单独的字段进行相同的计算。但是$match
可能只是最好的想法,如果确实存在其他你不想要的状态值。
答案 1 :(得分:1)
使用$ group两次和$ push的另一个答案,在下面这个查询中你需要计算UI端的最终总数。
db.collection.aggregate([
{
"$group": {
"_id": {
"username": "$username",
"status": "$status"
},
"statuscount": {
"$sum": 1
}
}
},
{
"$group": {
"_id": "$_id.username",
"finalstatus": {
"$push": {
"Status": "$_id.status",
"statuscount": "$statuscount"
}
}
}
}
])