在Mongo DB聚合匹配和查找查询之后计算字段的平均值

时间:2016-08-22 13:12:20

标签: mongodb mongodb-query aggregation-framework

我有两个Mongo数据库集合, req res

req 的格式为 -

{
    "_id" : ObjectId("asdasdasdasdasd"),
    "req" : {
        "url" : "/some/url",
        "method" : "GET",
    },
    "fieldA" : "ABCPQR",
    "time" : "2016-08-05T00:02:25.633Z",
}

集合 res 看起来像这样 -

{
    "_id" : ObjectId("jhtuyiogjhknmkvjhjkbhj"),
    "time" : "2016-08-05T00:00:11.272Z",
    "duration" : 106,
    "fieldB" : "ABCPQR"
}

我想要做的是..对于某种请求,即 req.url 的位置相同..我想计算持续时间的平均值 res 对象上的字段。

所以我聚集了 res 这样的对象 -

db.req.aggregate([
    { $match : { 'req.url' : '/some/url' } },
    { $lookup : { from : 'res', localField : 'fieldA', foreignField : 'fieldB', as : 'combined'} },
])

这就是输出的样子 -

{
    "_id" : ObjectId("asdasdasdasdasd"),
    "req" : {
        "url" : "/device/apps/updates?sync=false",
        "method" : "POST",
    },
    "fieldA" : "34e92ab8-a037-4d39-b151-94cd3f1a34e7",
    "time" : "2016-08-05T00:00:11.166Z",
    "combined" : [ 
        {
            "_id" : ObjectId("57b452b70be0f24aec4cc204"),
            "time" : "2016-08-05T00:00:11.272Z",
            "duration" : 106,
            "fieldB" : "34e92ab8-a037-4d39-b151-94cd3f1a34e7"
        }
    ]
}

现在计算一下,我在聚合查询中添加了一个 -

db.req.aggregate([
    { $match : { 'req.url' : '/some/url' } },
    { $lookup : { from : 'res', localField : 'fieldA', foreignField : 'fieldB', as : 'combined'} },
    { $group: { _id: '$fieldA', avg : { $avg : '$combined.duration' } } }
])

但它根本不产生任何输出。我做错了什么以及如何获得此持续时间字段的平均值?

1 个答案:

答案 0 :(得分:1)

根据documentation

  

在$ group阶段,如果表达式解析为数组,则为$ avg   将操作数视为非数值。

  

$ avg忽略非数字值。如果平均值的所有操作数都是   非数字,$ avg返回null。

您可以添加$unwind阶段将数组解构为多个文档,然后在对它们进行分组时使用$avg运算符

db.req.aggregate([
  { $match : { 'req.url' : '/some/url' } },
  { $lookup : { from : 'res', localField : 'fieldA', foreignField : 'fieldB', as : 'combined'} },
  { $unwind: '$combined' },
  { $group: { _id: 'avg_duration', avg : { $avg : '$combined.duration' } } }
]);