仅汇总MongoDB文档中的数组的现有元素

时间:2018-10-09 13:24:35

标签: arrays node.js mongodb mongoose aggregation-framework

我将数据存储在mongodb文档的集合中,如下所示。

{"_id":1536921044022.3953,
"flow":[
    {"_id":1536921044279.358,"y":0.1,"i":375,"t":33.1},
    {"_id":1536921044914.2346,"y":0.2,"i":310,"t":40.9},
    {"_id":1536921045548.5076,"y":0.3,"i":408,"t":32.9}],
"__v":0}
{"_id":1536921044053.3254,
"flow":[
    {"_id":1536921044229.358,"y":0.4,"i":375,"t":33.1},
    {"_id":1536921044954.2346,"y":0.5,"i":310,"t":40.9},
    {"_id":1536921045514.506,"y":0.6,"i":408,"t":32.9}],
    {"_id":1536921045245.5056,"y":0.7,"i":408,"t":32.9}],
    {"_id":1536921045549.3076,"y":0.8,"i":408,"t":32.9}],
"__v":0}

我想聚合流字段中的数据,以便获得一个数组,该数组代表每个对应元素的$flow.y值的平均数据点。给定以上数据,结果应为[0.25, 0.35, 0.45, 0.7, 0.8]。请注意,流数组的每个可用y字段已在所有文档中平均。第二个文档的最后两个元素将以0.70.8的形式返回,因为它们在前一个元素中不存在。因此,现有条目的平均值仅为这两个值,而不是您可能期望的0.350.4。如果存在带有0.12, 0.13的第三个文档,则返回的元素将是0.410.465

我一直在尝试将$arrayElemAt$elemMatch$avg的组合作为聚合管道的一部分,但是我似乎找不到正确的语法。

到目前为止,这是我的进度(nodejs):

for (i=0;i<10;i++) {
  ModelName.aggregate([
    { $project: { pulse: { $objectToArray: { $arrayElemAt: ["$flow", i]} } } },
    { $unwind: "$pulse" },
    { $match: { "pulse.k": "y" }},
    { $group: { _id: "$pulse.k", 
              count: { $sum: 1 },
              average: { $avg: "$pulse.v" },
              total: { $sum: "$pulse.v" }}}
  ], function (err, result) {
    console.log(err, result);
    running.push(result[0].average);
  });
};

它将返回每个文档的每个子文档元素的y字段的平均值。所以到了。剩下的主要障碍是删除循环并否定没有匹配元素的数组。我想象要完成后者,我将必须对现有数组元素进行连续计数,并除以每个平均值。

1 个答案:

答案 0 :(得分:1)

您可以将$unwindincludeArrayIndex选项一起使用,这将为您提供初始数组中的顺序,您可以通过该值$group进行尝试,

db.model.aggregate([
    {
        $unwind: {
            path: "$flow",
            includeArrayIndex: "index"
        }
    },
    {
        $group: {
            _id: "$index",
            value: { $avg: "$flow.y" }
        }
    },
    {
        $sort: { _id: 1 }
    },
    {
        $group: {
            _id: null,
            values: { $push: "$value" }
        }
    }
])

输出:{ "_id" : null, "values" : [ 0.25, 0.35, 0.44999999999999996, 0.7, 0.8 ] }