Mongo:对多个文档的嵌套数组的每个位置求平均值



我收到了一系列文档,每个文档都有一些研究参与者的数据。

"a";具有一些解剖学度量,这里表示为";foo";以及";条";。(即身高、体重等("b";在其他测试中具有每秒性能:"t〃;是以秒为单位的时间,并且"e";是在特定时间测量的测试结果。(即心率、血压、温度等(

数据示例:

[
{
"a": { "foo":1, "bar": 100 },
"b": [
{ "t":1, "e":[3,4,5] },
{ "t":2, "e":[4,4,4] },
{ "t":3, "e":[7,4,7] }
],
},

{
"a": { "foo":2, "bar": 111 },
"b": [
{ "t":1, "e":[9,4,0] },
{ "t":2, "e":[1,4,2] },
{ "t":3, "e":[3,4,5] }
],
},

{
"a": { "foo":4, "bar": 200 },
"b": [
{ "t":1, "e":[1,4,2] },
{ "t":2, "e":[3,1,3] },
{ "t":3, "e":[2,4,1] }
],
}
]

我正试图得到参与者的一些平均值。我已经设法得到存储在";a";。我用过:

db.collection.aggregate([
{
$group: {
_id: null,
barAvg: {
$avg: {
$avg: "$a.bar"
}
}
}
}
])

然而,我没能得到每秒每个测试的平均值。因此,这将是每个";t〃;对于";e";。

预期结果:

"average": [
{ "t":1, "e":[4.33, 3.00, 2.33] },
{ "t":2, "e":[2.66, 3.00, 3.00] },
{ "t":3, "e":[4.33, 3.00, 5.00] }
]

这里,4.33是每个人第一次测试(e[0](的平均值,但只是第一次测试的平均值(t=1(。

一个选项是$unwind根据文档的t值进行分离,并在计算平均值之前使用$zip进行转置:

db.collection.aggregate([
{$unwind: "$b"},
{$group: {_id: "$b.t", data: {$push: "$b.e"}}},
{$set: {data: {$zip: {inputs: [
{$arrayElemAt: ["$data", 0]},
{$arrayElemAt: ["$data", 1]},
{$arrayElemAt: ["$data", 2]}
]
}
}
}
},
{$project: {
t: "$_id",
e: {$map: {input: "$data", in: {$trunc: [{$avg: "$$this"}, 2]}}}
}
},
{$sort: {t: 1}},
{$group: {_id: 0, average: {$push: {t: "$t", e: "$e"}}}},
{$unset: "_id"}
])

看看它是如何在操场上工作的例子-zip

另一种选择可能是两次$unwind,并从各个部分构建整个计算,但其优点是,您不需要为$arrayElemAt:实际指定每个e阵列中的项目数

db.collection.aggregate([
{$project: {b: 1, t: 1, _id: 0}},
{$unwind: "$b"},
{$unwind: {path: "$b.e", includeArrayIndex: "index"}},
{$group: {_id: {t: "$b.t", index: "$index"}, data: {$push: "$b.e"}}},
{$sort: {"_id.index": 1}},
{$group: {_id: "$_id.t", average: {$push: {$avg: "$data"}}}},
{$sort: {_id: 1}},
{$group: {_id: 0, average: {$push: {t: "$_id", e: "$average"}}}},
{$unset: "_id"}
])

看看它是如何在操场上工作的例子-放松两次

最新更新