MongoDB 聚合对动态键进行分组

标签 mongodb mongodb-query aggregation-framework

我正在研究可变数量条形行的值的计数聚合,如下数据结构所示:

> 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/

相关文章:

javascript - Mongoose 如何在日期范围内查询并提取每天的最高值?

mongodb - 展开,但在每个结果行中保留原始数组

java - MongoDB + Java : no $db stored with DbRef?

python - 如何在 python/mongodb/elementTree 中将列表项转换为相应的字典

mongodb - findOneAndUpdate(updateQuery, updateSet, returnFields) 的返回类型是什么,如何获取返回值?

mongodb - 大量集合的聚合管道缓慢

node.js - MongoDB:查询以将数组中的每个元素与条件匹配

c# - 在 Mongo .NET 2.0 驱动程序中捕获 MongoAuthenticationException

javascript - 仅当文档中不存在提供者时才更新提供者数组并增加计数

java - Json 数组上的 Mongodb 聚合(JAVA)