我正在研究可变数量条形行的值的计数聚合,如下数据结构所示:
> db.data.find()
{ "_id" : "foo1", "1" : { "bar" : 6 }, "0" : { "bar" : 11 }, "3" : { "bar" : 8 }, "2" : { "bar" : 0 }, "5" : { "bar" : 8 }, "4" : { "bar" : 19 }, "6" : { "bar" : 8 } }
{ "_id" : "foo2", "1" : { "bar" : 18 }, "0" : { "bar" : 3 }, "3" : { "bar" : 19 }, "2" : { "bar" : 0 }, "5" : { "bar" : 13 }, "4" : { "bar" : 17 }, "7" : { "bar" : 8 }, "6" : { "bar" : 8 }, "8" : { "bar" : 8 } }
{ "_id" : "foo3", "1" : { "bar" : 0 }, "0" : { "bar" : 2 }, "3" : { "bar" : 18 }, "2" : { "bar" : 2 }, "4" : { "bar" : 12 } }
我可以单独执行此操作,但是否可以在整个数据集中执行此操作?输出格式对我来说并不重要,但这里有一个想法:
所需输出:
bar0: 16
bar1: 24
bar2: 2
bar3: 45
bar4: 48
bar5: 21
bar6: 16
bar7: 8
bar8: 8
最佳答案
您可以使用 MongoDB 的 aggregation 来做到这一点框架:
db.collection.aggregate([
/** Remove not needed fields, which will lessen size of doc */
{ $project: { _id: 0 } },
/** As you've dynamic field names - convert each field in doc into {k:...,v:...} & entire doc is pushed into array field `data` */
{
$project: { data: { $objectToArray: "$$ROOT" } }
},
{
$unwind: "$data"
},
/** group to bring same 'k' values together & sum-up bar value */
{
$group: { _id: "$data.k", bar: { $sum: "$data.v.bar" } }
},
/** Can be Optional, Project needed fields `data` will be an object */
{
$project: {
_id: 0,
data: { $arrayToObject: [ [ { "k": { $concat: [ "bar", "$_id" ] }, "v": "$bar" } ] ] } }
},
/** Make `data` field as new root for doc */
{
$replaceRoot: {
newRoot: "$data"
}
}
])
测试: mongoplayground
注意:尽量不要使用动态键名 - 这会导致读取时出现许多问题,而且 $group
之后的阶段在上面的查询中是可选的,它们在那里为了让输出看起来像所需的格式,最好测试直到 $group
阶段并检查它是否适合您的需要。
关于MongoDB 聚合对动态键进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61462351/