Javascript Mongo将多个文档聚合为一个文档

Javascript Mongo将多个文档聚合为一个文档,javascript,mongodb,aggregate,Javascript,Mongodb,Aggregate,我试图通过mongodb.collection.aggregate()命令合并一些复杂的文档 假设我想要合并集合文档的x(在下面的示例中:x=2): [ { “_id”:1, “数据”:{ “儿童”:{ "1": { “名称”:“仅在第一个文档中显示”, “成本”:1, “收入”:4.5, “孙子女”:{ “1t9dsqdqdvoj8pdppxjk”:{ “成本”:0, “收入”:1.5 } } }, "2": { “名称”:“出现在两个文档中”, “成本”:2, “收入”:7, “孙子女”:{

我试图通过mongodb.collection.aggregate()命令合并一些复杂的文档

假设我想要合并集合文档的x(在下面的示例中:x=2):

[
{
“_id”:1,
“数据”:{
“儿童”:{
"1": {
“名称”:“仅在第一个文档中显示”,
“成本”:1,
“收入”:4.5,
“孙子女”:{
“1t9dsqdqdvoj8pdppxjk”:{
“成本”:0,
“收入”:1.5
}
}
},
"2": {
“名称”:“出现在两个文档中”,
“成本”:2,
“收入”:7,
“孙子女”:{
“jesrdt5qwef2222dgt”:{
“成本”:1,
“收入”:3
},
“klh352hk5367kf”:{
“成本”:2,
“收入”:7
}
}
}
}
}
},
{
“_id”:2,
“数据”:{
“儿童”:{
"2": {
“名称”:“出现在两个文档中,但名称不同”,
“成本”:9,
“收入”:7,
“孙子女”:{
“AAAAAAAA”:{
“成本”:3,
“收入”:2
},
“jesrdt5qwef2222dgt”:{
“成本”:6,
“收入”:5
}
}
},
"3": {
“名称”:“仅出现在上次单据中”,
“成本”:4,
“收入”:2,
“孙子女”:{
“CCCC”:{
“成本”:4,
“收入”:2
}
}
}
}
}
}
]
挑战:

  • 在编写查询时,“children”和“sunderren”键下的键是动态的和未知的
  • 如果子女或孙辈仅出现在一份文件中(如“1”、“3”、“1t9dsqdqdvoj8pdppxjk”、“klh352hk5367kf”、“AAAAAAA”和“CCCCCC”),则其也应出现在最终结果中
  • 如果一个子项出现在多个文档中(例如“2”和“jesrdt5qwef2222dgt”)-它应在最终结果中显示为一个。“成本”和“收入”字段应相加,最后一个“名称”字段应为
  • 我看到了以下解决方案:

  • -不相关,2个不同的集合
  • -不相关,不能对多次出现的字段值求和(取而代之的是最后一个字段)
  • -不相关,不能对多次出现的字段值求和(取而代之的是最后一个字段)
  • 最终结果应如下所示:

    {
    “数据”:{
    “儿童”:{
    "1": {
    “名称”:“仅在第一个文档中显示”,
    “成本”:1,
    “收入”:4.5,
    “孙子女”:{
    “1t9dsqdqdvoj8pdppxjk”:{
    “成本”:0,
    “收入”:1.5
    }
    }
    },
    "2": {
    “名称”:“出现在两个文档中,但名称不同”,
    “成本”:11,
    “收入”:14,
    “孙子女”:{
    “AAAAAAAA”:{
    “成本”:3,
    “收入”:2
    },
    “jesrdt5qwef2222dgt”:{
    “成本”:7,
    “收入”:8
    },
    “klh352hk5367kf”:{
    “成本”:2,
    “收入”:7
    }
    }
    },
    "3": {
    “名称”:“仅出现在上次单据中”,
    “成本”:4,
    “收入”:2,
    “孙子女”:{
    “CCCC”:{
    “成本”:4,
    “收入”:2
    }
    }
    }
    }
    }
    }
    
    这是一个有点长的过程,可能会有一些简单的过程,我只是在分享这个过程

    • $project
      子项
      转换为数组格式(k,v)
    • $unwind
      deconstruct
      children
      array
    • $group
      按子项,对
      成本
      收入
      进行求和,并使用
      $last
      获取last
      名称
    • $unwind
      解构
      孙子辈
      数组
    • $addFields
      孙子辈
      转换为数组格式(k,v)
    • $unwind
      解构
      孙子辈
      数组
    • $group
      子项
      键和
      孙子项
      键,计算孙子项的成本和收入之和
    • $group
      子项
      键并重新构造
      子项
      数组
    • $group
      null
      重新构造子数组,并使用
      $arrayToObject
      孙辈
      从(k,v)数组转换为对象
    • $project
      使用
      $arrayToObject

    太棒了!先生,你真是个职业选手!!我可以在操场上看到一切都很好,所以我将开始阅读您添加的功能-THX!只有一件事不能正常工作:id为“2”的孩子的成本和收入取最后的值,而不是总和(孙子孙女的总和是正确的)好的,很抱歉,这将很快检查并更新您。
    db.collection.aggregate([
      { $project: { "Data.children": { $objectToArray: "$Data.children" } } },
      { $unwind: "$Data.children" },
      {
        $group: {
          _id: "$Data.children.k",
          name: { $last: "$Data.children.v.name" },
          cost: { $sum: "$Data.children.v.cost" },
          revenue: { $sum: "$Data.children.v.revenue" },
          grandchildren: { $push: "$Data.children.v.grandchildren" }
        }
      },
      { $unwind: "$grandchildren" },
      { $addFields: { grandchildren: { $objectToArray: "$grandchildren" } } },
      { $unwind: "$grandchildren" },
    
      {
        $group: {
          _id: {
            ck: "$_id",
            gck: "$grandchildren.k"
          },
          cost: { $first: "$cost" },
          revenue: { $first: "$revenue" },
          name: { $first: "$name" },
          grandchildren_cost: { $sum: "$grandchildren.v.cost" },
          grandchildren_revenue: { $sum: "$grandchildren.v.revenue" }
        }
      },
    
      {
        $group: {
          _id: "$_id.ck",
          cost: { $first: "$cost" },
          revenue: { $first: "$revenue" },
          name: { $last: "$name" },
          grandchildren: {
            $push: {
              k: "$_id.gck",
              v: {
                cost: "$grandchildren_cost",
                revenue: "$grandchildren_revenue"
              }
            }
          }
        }
      },
    
      {
        $group: {
          _id: null,
          children: {
            $push: {
              k: "$_id",
              v: {
                name: "$name",
                cost: "$cost",
                revenue: "$revenue",
                grandchildren: { $arrayToObject: "$grandchildren" }
              }
            }
          }
        }
      },
    
      {
        $project: {
          _id: 0,
          "Data.children": { $arrayToObject: "$children" }
        }
      }
    ])