【问题标题】:MongoDB - $gruop, secondary $group, $sum fields using multiple lookupsMongoDB - 使用多个查找的 $gruop、辅助 $group、$sum 字段
【发布时间】:2019-04-17 08:00:45
【问题描述】:

我正在尝试使用 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*) },
                 ]
     },
]

如果有人可以尝试弄清楚如何通过单个聚合调用来实现此行为,我会很高兴。我尝试了许多管道运算符的组合,但似乎无济于事。

【问题讨论】:

    标签: node.js mongodb typescript mongodb-query aggregation-framework


    【解决方案1】:

    尝试如下:

    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
            }
        ]
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多