MongoDB 聚合 : How to put results from lookup into a nested array?

标签 mongodb aggregation-framework

我正在尝试聚合以下文档以使参与者作为嵌套数组中的对象。

{
  "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. 在第四步中,我将使用项目删除给定参与者的不必要字段。
  5. 在第五步中,我再次使用 unwind 来获取单个参与者(我知道也可以使用 $first 运算符)
  6. 在第六步我将它分组

我正在尝试将第 3 步中的每个参与者添加到参与者数组中的相应日程对象中,文档应该是这样的:

  {
    "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"
          },
          
        ],
        
      },
      
    ], 
  }

最佳答案

你的想法是正确的,你可以简化你的管道从而使重建更容易,第二个 $unwind 是多余的,删除它将使我们只使用一组来重建对象阶段。这显然要简单得多。

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 聚合 : How to put results from lookup into a nested array?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74192910/

相关文章:

node.js - mongodb可以查询当月、季度、学期的销售额吗?

java - Spring mongo聚合按日期范围获取计数和日期

mongodb - 如何将mongo-connector与许多集合以及每个集合的特定字段一起使用?

mongodb 的 php 驱动程序不工作并给出奇怪的警告

javascript - 没有字段名称的 Mongoose 结构聚合输出

Mongodb 对内部数组进行排序

mongodb - 具有超过 1 个数组的 Mongodb 聚合文档

r - 在 mongoDB/mongolite 中用来编写函数的是什么?

mongodb - 由于 x509 证书依赖于旧的 Common Name 字段,因此无法使用 Golang 连接到服务器

mongodb - 在 MongoDB 中,如何使用文档中的字段作为 $geoWithin/$centerSphere 表达式的输入?