{"_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.7 , 0.8 因为它们在前一个中不存在。因此,现有条目的平均值只是这两个值,而不是 0.35 , 0.4 如你所料。如果有第三份文件 0.12, 0.13 那么返回的元素将是 0.41 0.465 .
$flow.y
[0.25, 0.35, 0.45, 0.7, 0.8]
y
0.7
0.8
0.35
0.4
0.12, 0.13
0.41
0.465
我一直在尝试 $arrayElemAt , $elemMatch , $avg
$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 每个文档的每个子文档元素的字段。所以它正在到达那里。剩下的关键障碍是移除循环和否定没有匹配元素的数组。我想要实现后者,我必须保持现有数组元素的运行计数,并除以每个平均数。
你可以用 $unwind 具有 includeArrayIndex 选项,它将为您提供初始数组中的顺序和 $group
includeArrayIndex
$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 ] }
{ "_id" : null, "values" : [ 0.25, 0.35, 0.44999999999999996, 0.7, 0.8 ] }