【问题标题】:Join two collections with id stored in array of objects in mongodb加入两个集合,其中 id 存储在 mongodb 的对象数组中
【发布时间】:2021-01-21 23:01:20
【问题描述】:

我有两个名为 SchoolStudents

的集合

学校收藏

   {
      _id: ObjectId("60008e81d186a82fdc4ff2b7"),
      name: String,
      branch: String,  
      class: [{
             "active" : true,
             "_id" : ObjectId("6001e6871d985e477b61b43f"),
             "name" : "I",
             "order" : 1
        }, 
        {
             "active" : true,
             "_id" : ObjectId("6001e68f1d985e477b61b444"),
             "name" : "II",
             "order" : 2
        }]
   }

学生收藏

  {
      _id: ObjectId("6002def815eccd53a596f830"),
      schoolId: ObjectId("60008e81d186a82fdc4ff2b7"),
      sessionId: ObjectId("60008e81d186a82fdc4ff2b9"),
      class: ObjectId("6001e6871d985e477b61b43f"),
   }

我想在单个查询中获取Student Collection的数据。

我的班级id 存储在学生集合中,针对该id 的数据存储在学校集合中的类键下,这是一个对象数组。

您能帮我在学生集合中获取具有此 ID 的类对象吗?

我想要的输出:

data: {
  _id: ObjectId("6002def815eccd53a596f830"),
  schoolId: ObjectId("60008e81d186a82fdc4ff2b7"),
  sessionId: ObjectId("60008e81d186a82fdc4ff2b9"),
  class: ObjectId("6001e6871d985e477b61b43f"),
  classData: [{
        "active" : true,
        "_id" : ObjectId("6001e6871d985e477b61b43f"),
        "name" : "I",
        "order" : 1
    }]

}

所以我尝试了这个,但没有成功:

const students = await this.studentModel.aggregate([
{
  $lookup: {
    from: 'School',
    let: { classId: '$class' },
    pipeline: [
      {
        $match: {
          $expr: { $eq: ['$$classId', '$class._id'] },
        },
      },
    ],
    as: 'classData',
  },
},
]);

【问题讨论】:

  • 在您的查询中尝试使用$in 而不是$eq
  • @turivishal 我试过没用
  • 确保集合名称 SchoolSchools 在数据库中。
  • 是的,他们都是学校和学生,问题在于查询。
  • 当你使用$in而不是$eq时,查询看起来不错,在本地机器上测试过。

标签: mongodb mongodb-query aggregation-framework mongoose-schema mongoose-populate


【解决方案1】:
  • $lookup,通过schoolIdclass 进入let
  • $match学校身份证条件
  • $filter 迭代 class 的循环并过滤特定的类对象
  • $arrayElemAt 将从$filter 返回的结果中获取对象
  • $replaceRoot 将对象替换为根
const students = await this.studentModel.aggregate([
  {
    $lookup: {
      from: "School",
      let: {
        schoolId: "$schoolId",
        classId: "$class"
      },
      pipeline: [
        { $match: { $expr: { $eq: ["$$schoolId", "$_id"] } } },
        {
          $replaceRoot: {
            newRoot: {
              $arrayElemAt: [
                {
                  $filter: {
                    input: "$class",
                    cond: { $eq: ["$$this._id", "$$classId"] }
                  }
                },
                0
              ]
            }
          }
        }
      ],
      as: "classData"
    }
  }
])

Playground

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 2020-05-12
    • 2017-08-10
    • 2020-09-03
    相关资源
    最近更新 更多