我正在try 聚合以下文档,以将参与者作为嵌套数组中的对象.

{
  "name": "EXAMPLE",
  "schedules": [
    {
      "schedule_id":  "id1",
      "participants": [
      "participant_id1",
      "participant_id2"
      ],
    },
    {
      "schedule_id": "id2",
      "participants": [
        "participant_id1",
        "participant_id2"
      ],
    },
    {
      "schedule_id": "id3",
      "participants": [
        "participant_id1"
      ],
    },
  ],
}

因此,我写了以下管道:

[
  {
    $unwind: {
      path: "$schedules",
      includeArrayIndex: "index",
      preserveNullAndEmptyArrays: true,
      
    }
  },
  {
    $unwind: {
      path: "$schedules.participants",
      includeArrayIndex: "index",
      preserveNullAndEmptyArrays: true,
      
    }
  },
  {
    $lookup: {
      from: "customers",
      localField: "schedules.participants",
      foreignField: "_id",
      as: "participants",
      
    }
  },
  {
    $project: {
      "participants.address": 0,
      "participants.birthday": 0,
      
    }
  },
  {
    $unwind: {
      path: "$participants",
      preserveNullAndEmptyArrays: true,
      
    }
  },
  {
    $group:
    {
      _id: "$_id",
      name: {
        $first: "$name",
        
      },
      schedules: {
        $first: "$schedules",
        
      },
      
    }
  },
  
]
  1. 此管道中的第一步是展开时间表数组,以获得文档中的每个单独时间表.
  2. 第二步是展开参与者,因为我需要参与者ID来执行第三步中的查找过程.
  3. 第三步是在Customers集合中查找参与者,返回的将是一个Customer对象.
  4. 在第四步中,我将使用project从给定参与者中删除不必要的字段.
  5. 在第五步中,我再次使用展开来获取单个参与者(我知道也可以使用$First运算符)
  6. 在第六步,我将对其进行分组

我正在try 将步骤3中的每个参与者添加到参与者数组中的相应日程对象,即document should be like this:

  {
    "name": "EXAMPLE",
    "schedules": [
      {
        "schedule_id": "id1",
        "participants": [
          {
            id: "id1",
            "name": "name1"
          },
          {
            id: "id2",
            "name": "name2"
          },
          
        ],
        
      },
      {
        "schedule_id": "id2",
        "participants": [
          {
            id: "id1",
            "name": "name1"
          },
          {
            id: "id2",
            "name": "name2"
          },
          
        ],
        
      },
      {
        "schedule_id": "id3",
        "participants": [
          {
            id: "id1",
            "name": "name1"
          },
          
        ],
        
      },
      
    ], 
  }

推荐答案

你的 idea 是正确的,你可以简化你的管道,从而使它更容易重建,第二个$unwind是多余的,丢弃它将允许我们只使用1个分组阶段来重建对象.这显然要简单得多.

db.collection.aggregate([
  {
    $unwind: {
      path: "$schedules",
      includeArrayIndex: "index",
      preserveNullAndEmptyArrays: true,
      
    }
  },
  {
    $lookup: {
      from: "customers",
      localField: "schedules.participants",
      foreignField: "_id",
      as: "participants",
      
    }
  },
  {
    $project: {
      "participants.address": 0,
      "participants.birthday": 0,
      
    }
  },
  {
    $group: {
      _id: "$_id",
      schedules: {
        $push: {
          schedule_id: "$schedules.schedule_id",
          participants: "$participants"
        }
      },
      name: {
        $first: "$name"
      }
    }
  }
])

Mongo Playground

Mongodb相关问答推荐

MongoDB聚合匹配字符串字符

Mongo聚合项目数组交集

如何在MongoSH中的现有文档中插入字段

在mongdob中按子文档筛选不起作用

为什么使用 Golang Mongo 驱动程序进行简单查询需要超过 2 秒?

如何使用 MindsDB 和 MQL(对于我的 MongoDB 实例)实施零样本分类?

mongo:在 mongodb 6.0 docker 容器上找不到命令

MongoError:$subtract 累加​​器是一元运算符

更新 MongoDB 中嵌套实体数组中的属性

mongoose默认值等于其他值

mongo _id 字段重复键错误

将 MongoDB 地理空间索引与 3d 数据结合使用

为什么mongodb的文档中存储键名

在 Mongoose 中填写所有必填字段

为什么使用 Redis 而不是 MongoDb 进行缓存?

为什么我新创建的 mongodb 本地数据库增长到 24GB?

如何判断 MongoDB 中是否存在字段?

错误:需要数据和盐参数

mongoose中的 Date.now() 和 Date.now 有什么区别?

聚合 $lookup 匹配管道中文档的总大小超过最大文档大小