MongoDB聚合与数组值的总和

标签 mongodb mongodb-query aggregation-framework

我有一个包含以下数据的集合:

{
    "_id" : ObjectId("5516d416d0c2323619ddbca8"),
    "date" : "28/02/2015",
    "driver" : "user1",
    "passengers" : [
        {
            "user" : "user2",
            "times" : 2
        },
        {
            "user" : "user3",
            "times" : 3
        }
    ]
}
{
    "_id" : ObjectId("5516d517d0c2323619ddbca9"),
    "date" : "27/02/2015",
    "driver" : "user2",
    "passengers" : [
        {
            "user" : "user1",
            "times" : 2
        },
        {
            "user" : "user3",
            "times" : 2
        }
    ]
}

并且我想执行聚合,以便我知道某个乘客的时间,它与某个司机在一起,在我的示例中它将是: 对于 user1:[{ driver: user2, times: 2}] 对于 user2:[{ driver: user1, times: 2}] 对于 user3:[{ driver: user1, times: 3}, {driver: user2, times:2}]

我对 mongo 很陌生,并且知道如何使用 sum 执行简单的聚合,但不是当它在数组内部时,以及当我的主题本身在数组中时。 执行这种聚合的适当方法是什么,更具体地说,我如何在基于 express.js 的服务器中执行它?

最佳答案

要使用聚合框架满足您的需求,第一个管道阶段将是 $match对相关乘客的操作,将文档与乘客数组中的用户匹配,然后是 $unwind从前一个操作中的输入文档中解构乘客数组的操作,为每个元素输出一个文档。解构后的数组上的另一个 $match 操作进一步过滤先前的文档流,只允许匹配的文档未经修改地传递到下一个管道阶段,即投影所需字段与 $project运算符(operator)。所以基本上你的 user3 聚合管道将像:

db.collection.aggregate([
     {
        "$match": {
            "passengers.user": "user3"
        }
     },
     {
         "$unwind": "$passengers"
     },
     {
        "$match": {
            "passengers.user": "user3"
        }
     },
     {
         "$project": {
             "_id": 0,
            "driver": "$driver",
            "times": "$passengers.times"
        }
     }
])

结果:

/* 0 */
{
    "result" : [ 
        {
            "driver" : "user1",
            "times" : 3
        }, 
        {
            "driver" : "user2",
            "times" : 2
        }
    ],
    "ok" : 1
}

更新:

如您所提到的,要对具有不同日期的驱动程序上的重复项进行分组,您可以执行 $group在最后一个 $project 管道阶段之前的操作,您使用 $sum 运算符计算总乘客时间:

db.collection.aggregate([
     {
        "$match": {
            "passengers.user": "user3"
        }
     },
     {
         "$unwind": "$passengers"
     },
     {
        "$match": {
            "passengers.user": "user3"
        }
     },
     {
         "$group": {
             "_id": "$driver", 
             "total": {
                 "$sum": "$passengers.times"
             }
         }
     },
     {
         "$project": {
            "_id": 0,
            "driver": "$_id",
            "total": 1
        }
     }
])

结果:

/* 0 */
{
    "result" : [ 
        {
            "total" : 2,
            "driver" : "user2"
        }, 
        {
            "total" : 3,
            "driver" : "user1"
        }
    ],
    "ok" : 1
}

关于MongoDB聚合与数组值的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29319799/

相关文章:

mongodb - MongoDB 中是否有 NOW() 的等效项

linux - 在 centos 6.5(64bits) 上安装 mongodb 时出错

javascript - MongoDB - 列表中每个 ID 的最新项目

mongodb - MongoDB中count()和find().count()的区别

javascript - Mongoose :聚合和计数

node.js - Mongodb $addFields,从函数返回字段值?

node.js - 在 expressJS 中处理 mongodb 连接

MongoDB 对结构未知的子文档进行文本搜索

java - Mongodb java驱动程序查询转换

MongoDB 扁平化字典列表中某些字段的结果列表