Mongo 嵌套数组分组,保留原始数据聚合框架

Mongo group by nested array, preserving original data Aggregation Framework

我有以下架构,我在 JS 中使用带有 mongoose 的聚合框架

{
 id: 1,
 name: Alfred,
 age: 10,
 orders:[

   {type:"A",address:"Address1"},
   {type:"A",address:"Address2"},
   {type:"B",address:"Address4"},
   {type:"B",address:"Address5"},
   {type:"B",address:"Address6"},
   ...
 ]
},
{
 id: 2,
 name: Bren,
 age: 15,
 orders:[

   {type:"B",address:"Address1"},
   {type:"B",address:"Address2"},
   {type:"B",address:"Address4"},
   {type:"A",address:"Address5"},
   {type:"B",address:"Address6"},
   ...
 ]
}

我正在尝试获取此输出

{
 id: 1,
 name: Alfred,
 age:10,

 countTypeA:2,
 countTypeB:3
},
{
 id: 2
 name: Bren,
 age: 15,
 
 countTypeA: 1,
 countTypeB: 4
}

我试过使用 $unwind$group:{_id:"orders.type"} 但我丢失了每一行的原始数据(姓名、年龄),我不介意丢失地址信息,我'我有兴趣计算每个用户在其订单列表中的订单类型。

  1. $unwind - 将 orders 数组解构为多个文档。
  2. $group - 按 idorders.type 分组。并通过 $first.
  3. 存储其他属性
  4. $group - 按 id 分组。通过 $first 存储其他属性。并使用 key-value 对文档创建 type 数组。
  5. $replaceRoot - 用所需文档替换输入文档。
  6. $unset - 删除 type 字段。
db.collection.aggregate([
  {
    $unwind: "$orders"
  },
  {
    $group: {
      _id: {
        id: "$id",
        type: "$orders.type"
      },
      name: {
        $first: "$name"
      },
      age: {
        $first: "$age"
      },
      count: {
        $sum: 1
      }
    }
  },
  {
    $group: {
      _id: "$_id.id",
      name: {
        $first: "$name"
      },
      age: {
        $first: "$age"
      },
      type: {
        $push: {
          k: {
            $concat: [
              "countType",
              "$_id.type"
            ]
          },
          v: "$count"
        }
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": {
        "$mergeObjects": [
          "$$ROOT",
          {
            "$arrayToObject": "$type"
          }
        ]
      }
    }
  },
  {
    $unset: "type"
  }
])

Sample Mongo Playground