我正在尝试使用mongo聚合查询来查看一堆数据,并以对我有用的方式对其进行检索。主要是因为我希望所有排序逻辑都在数据库上发生,而不是在服务器上手动完成。
所以我有 项目,用户,计时器
项目集合:
{id: 1, name: "project A"}
{id: 2, name: "project X"}
{id: 3, name: "project C"}
用户集合:
{id: 1, name: "John"}
{id: 2, name: "Jane"}
{id: 3, name: "James"}
计时器集合:
{id: 1, projectId: 3, userId: 2, startTime: (date ISO), endTime: (date ISO)}
{id: 2, projectId: 1, userId: 3, startTime: (date ISO), endTime: (date ISO)}
{id: 3, projectId: 1, userId: 1, startTime: (date ISO), endTime: (date ISO)}
{id: 4, projectId: 1, userId: 1, startTime: (date ISO), endTime: (date ISO)}
{id: 5, projectId: 2, userId: 1, startTime: (date ISO), endTime: (date ISO)}
我希望使用聚合从mongo中实现的是一个响应对象,该对象将反映“主要”类别的分组,其内部将按“次要”类别分组-每个条目将保存持续时间的总和(每个计时器的endTime减去startTime)
所以可以说我的主要小组是项目,而次要小组是用户,我还希望看到按字母顺序排列的名称,而不是ID。因此预期结果应该是:
[
{ project A: [
{ James: (*the sum of durations for all Jamses' timers on project 1*) },
{ John: (*the sum of durations for all John's timers on project 1*) },
]
},
{ project B: [
{ John: (*the sum of durations for all Jane's timers on project 3*) },
]
},
{ project X: [
{ Jane: (*the sum of durations for all John's timers on project 2*) },
]
},
]
如果有人可以尝试通过单个聚集调用实现此行为,我将很乐意。我已经尝试了管道运算符的许多组合,但是似乎无处可寻。
答案 0 :(得分:0)
尝试如下:
db.timers.aggregate(
[
{
$lookup: {
from: "users",
let: {"uId": "$userId" },
pipeline: [
{
$match: {
$expr: { $eq: ["$_id", "$$uId"] }
}
}
],
as: "userInfo"
}
},
{
$lookup: {
from: "project",
let: {"pId": "$projectId" },
pipeline: [
{
$match: {
$expr: { $eq: ["$_id", "$$pId"] }
}
}
],
as: "projectInfo"
}
},
{ $unwind: "$userInfo" },
{ $unwind: "$projectInfo" },
{
$group: {
_id: { "pname":"$projectInfo.name", "uname": "$userInfo.name" } ,
sumOfDurationInMinutes: { $sum: { $divide:[ { $subtract: ["$endTime", "$startTime"] }, 60000 ]} }
}
},
{
$group: {
_id: "$_id.pname",
data: { $push: "$$ROOT"}
}
}
]
)
响应结果:
{
"_id" : "project C",
"data" : [
{
"_id" : {
"pname" : "project C",
"uname" : "Jane"
},
"sumOfDurationInMinutes" : 60
}
]
},
/* 2 */
{
"_id" : "project A",
"data" : [
{
"_id" : {
"pname" : "project A",
"uname" : "John"
},
"sumOfDurationInMinutes" : 120
},
{
"_id" : {
"pname" : "project A",
"uname" : "James"
},
"sumOfDurationInMinutes" : 60
}
]
},
/* 3 */
{
"_id" : "project X",
"data" : [
{
"_id" : {
"pname" : "project X",
"uname" : "John"
},
"sumOfDurationInMinutes" : 60
}
]
}