【问题标题】:MongoDB client join on multiple CollectionsMongoDB客户端加入多个集合
【发布时间】:2020-04-13 22:37:25
【问题描述】:

我的收藏

预订量 - id,unitId

单位 - id,title,courseId

课程 - id,title

我想获取带有单元和课程名称的预订数组,如下所示

Boking_id Unit_title course_title

xxxx ABC XYZ

我当前的代码

const bookings   = await db.getDB().collection('bookings').aggregate([
  {
    $lookup:
    {
      from: 'courseUnit',
      localField: 'courseUnitId',
      foreignField: '_id',
      as: 'uu'
    }
  },
  {
      $unwind:"$uu"
  }
]).toArray();

【问题讨论】:

    标签: arrays mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您正在寻找的解决方案是通过在聚合管道中使用多次$lookup 管道来解决的。例如:

    db.Bookings.aggregate([
        { 
            "$lookup" : 
                {"from":  "Unit", "localField": "unitId", "foreignField": "_id", as : "UnitDetails"   } 
        }, 
        {
            "$unwind" : "$UnitDetails"
        },
        {
            $lookup:   
                { "from": "Course", "localField": "UnitDetails.courseId", "foreignField": "_id", as: "CouserDetails"    }  
        },
        {
            "$unwind" : "$CouserDetails"
        },
        {   
            $project:  {_id:0, "Boking_id" : "$_id",  "Unit_title": "$UnitDetails.title", "course_title": "$CouserDetails.title" } 
        }   
    
    ]).pretty()
    

    上述查询的输出如下:

    {
        "Boking_id" : ObjectId("5dff07e4187da4c2b5ffc59f"),
        "Unit_title" : "unit title for course title 3",
        "course_title" : "Title of the Course collection 3"
    }
    

    我在三个集合中的初始集合数据集如下:

    > db.Bookings.find()
    { "_id" : ObjectId("5dff07e4187da4c2b5ffc59f"), "unitId" : ObjectId("5dff06d6187da4c2b5ffc59e") }
    > db.Unit.find()
    { "_id" : ObjectId("5dff06d6187da4c2b5ffc59e"), "title" : "unit title for course title 3", "courseId" : ObjectId("5dff010d187da4c2b5ffc59b") }
    > db.Course.find()
    { "_id" : ObjectId("5dff0108187da4c2b5ffc599"), "title" : "Title of the Course collection" }
    { "_id" : ObjectId("5dff010b187da4c2b5ffc59a"), "title" : "Title of the Course collection 2" }
    { "_id" : ObjectId("5dff010d187da4c2b5ffc59b"), "title" : "Title of the Course collection 3" }
    { "_id" : ObjectId("5dff010f187da4c2b5ffc59c"), "title" : "Title of the Course collection 4" }
    > 
    

    详情请参考以下参考资料:

    1. How to join multiple collections with $lookup in mongodb
    2. Multiple join conditions using the $lookup operator
    3. Mongodb Join on _id field from String to ObjectId

    如果 Unit&Course 集合中的 unitId 和 courseId 的值存储为简单字符串,那么您必须使用 $toObjectId。我创建了另一组集合并使用了$toObjectId,如下所示:

    > db.Bookings2.find()
    { "_id" : ObjectId("5dff6c2a187da4c2b5ffc5a3"), "unitId" : "5dff66c9187da4c2b5ffc5a2" }
    > db.Unit2.find()
    { "_id" : ObjectId("5dff66c9187da4c2b5ffc5a2"), "title" : "Unit title 1", "courseId" : "5dff6694187da4c2b5ffc5a0" }
    > db.Course2.find()
    { "_id" : ObjectId("5dff6694187da4c2b5ffc5a0"), "title" : "Title of the Course collection 1" }
    { "_id" : ObjectId("5dff6694187da4c2b5ffc5a1"), "title" : "Title of the Course collection 2" }
    > 
    > db.Bookings2.aggregate([ {$project: {"unitObjectId" : {$toObjectId: "$unitId"}} },  {$lookup:  {"from": "Unit2", "localField": "unitObjectId", "foreignField": "_id", as:  "UnitDetails" }  }, {$unwind: "$UnitDetails"}, {$project: {"courseObjectId":   {$toObjectId:  "$UnitDetails.courseId" }, "unitTitle": "$UnitDetails.title"  } }, {$lookup:  {"from": "Course2", "localField": "courseObjectId", "foreignField": "_id", as:  "Course2Details"  }  }, {$unwind: "$Course2Details"}, {$project: {_id: 0, "Boking_id": "$_id",  "Unit_title":  "$unitTitle", "course_title": "$Course2Details.title" }  }    ]).pretty()
    {
        "Boking_id" : ObjectId("5dff6c2a187da4c2b5ffc5a3"),
        "Unit_title" : "Unit title 1",
        "course_title" : "Title of the Course collection 1"
    }
    > 
    

    【讨论】:

    • @NEET,注意 Unit 集合 courseId 的值是它的 ObjectId,而不是简单的字符串,这就是为什么我提供了参考,如果你有简单的字符串,然后按照参考解决问题。
    • 单位中的courseId是字符串,但它在课程集合中对_id的引用
    • @NEETJASSI 以上答案解决了你的问题吗?
    • @NEETJASSI 考虑到 courseId 以单位为单位的字符串值并更新了之前的答案,希望这个查询能解决你的问题。
    猜你喜欢
    • 2017-04-28
    • 2022-01-01
    • 1970-01-01
    • 2020-05-12
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    相关资源
    最近更新 更多