【问题标题】:How to do multiple joins between two collection in mongodb using lambda function?如何使用 lambda 函数在 mongodb 中的两个集合之间进行多个连接?
【发布时间】:2019-12-21 02:38:56
【问题描述】:

我有两个集合 1) user_posts 2)user_profile。查找以下收集数据供您参考。

1) user_posts 集合

_id :ObjectId("5d519f861c9d4400005ebd1b")
userid : ObjectId("5d518caed55bc00001d235c1")
media : "hello.jpg"
type : "jpg"
created : " "
modified : " "
like : Array
       0 : Object
           userid : ObjectId("5d518caed55bc00001d235c1")
           status : "like"
       1 : Object
           userid : ObjectId("5d518da6d55bc00001d235c2")
           status : "happy"
comment : Array
       0 : Object
           userid : ObjectId("5d518caed55bc00001d235c1")
           comment : "hello"
       1 : Object
           userid : ObjectId("5d518da6d55bc00001d235c2")
           comment : "welcome"
share : Array
       0 : Object
           userid : ObjectId("5d518caed55bc00001d235c1")
           status : "shared"
       1 : Object
           userid : ObjectId("5d518da6d55bc00001d235c2")
           status : "shared"

2) User_profile 集合

 _id : ObjectId("5d518caed55bc00001d235c1")
 username : "ramesh",
 photo :  " ",
 created : " ",
 modified : " "

 _id : ObjectId("5d518da6d55bc00001d235c2")
 username : "shekar",
 photo :  " ",
 created : " ",
 modified : " "

现在我尝试从 lambda 函数中的 user_profile 获取配置文件详细信息。但我没有得到细节。找到下面的 lambda 函数代码。

def lambda_handler(event, context):

print("Received event: " + json.dumps(event, indent=1))

user_posts = db.user_posts

Userid = event['userid']
uid = ObjectId(Userid)

dispost = list(user_posts.aggregate([{
"$match" : { "userid" : uid }
},
{ "$graphLookup" : 
     {
       "from" : "user_profile",
       "startWith" : "$like.userid",
       "connectFromField" : "like.userid",
       "connectToField" : "_id",
       "as" : "userdetails"
     }
},
{ "$graphLookup" : 
     {
       "from" : "user_profile",
       "startWith" : "$comment.userid",
       "connectFromField" : "comment.userid",
       "connectToField" : "_id",
       "as" : "userdetails1"
     }
}
{ "$graphLookup" : 
     {
       "from" : "user_profile",
       "startWith" : "$share.userid",
       "connectFromField" : "share.userid",
       "connectToField" : "_id",
       "as" : "userdetails2"
     }
}
]))     
disair = json.dumps(dispost, default=json_util.default)
return json.loads(disair)

但我没有得到输出。我需要像下面这样的输出。

_id :ObjectId("5d519f861c9d4400005ebd1b")
userid : ObjectId("5d518caed55bc00001d235c1")
username : "ramesh"
photo : " ",
media : "hello.jpg"
type : "jpg"
created : " "
modified : " "
like : Array
       0 : Object
           userid : ObjectId("5d518caed55bc00001d235c1")
           status : "like"
           username : "ramesh"
           photo : " "
       1 : Object
           username : "shekar"
           photo : " "
           userid : ObjectId("5d518da6d55bc00001d235c2")
           status : "happy"
           username : "shekar"
           photo : " "
comment : Array
       0 : Object
           userid : ObjectId("5d518caed55bc00001d235c1")
           comment : "hello"
           username : "ramesh"
           photo : " "
       1 : Object
           userid : ObjectId("5d518da6d55bc00001d235c2")
           comment : "welocme"
           username : "shekar"
           photo : " "
share : Array
       0 : Object
           userid : ObjectId("5d518caed55bc00001d235c1")
           status : "shared"
           username : "ramesh"
           photo : " "
       1 : Object
           userid : ObjectId("5d518da6d55bc00001d235c2")
           status : "shared"
           username : "shekar"
           photo : " "

你能帮我解决问题吗?提前致谢。

【问题讨论】:

    标签: mongodb aws-lambda pymongo


    【解决方案1】:

    请检查:

    db.collection("user_posts").aggregate(
    { $match: {"userid" : uid}},
    { $unwind: '$like' },
    { $lookup: { from: "users", localField: "like.userid", foreignField: "_id", as: 
    "users" }},
    { $group: {
        _id: "$_id",
        like: { $push: { $mergeObjects: ['$like', { $arrayElemAt: [ "$users", 0 ] } ]}},
        data: { $first: "$$ROOT" }
    }},
    { $replaceRoot: { newRoot: { $mergeObjects: ['$data', { like: "$like"} ]} } },
    { $unwind: '$comment' },
    { $lookup: { from: "users", localField: "comment.userid", foreignField: "_id", as: 
     "users" }},
    { $group: {
        _id: "$_id",
            comment: { $push: { $mergeObjects: ['$comment', { $arrayElemAt: [ "$users", 0 
     ] } ]}},
            data: { $first: "$$ROOT" }
    }},
    { $replaceRoot: { newRoot: { $mergeObjects: ['$data', { comment: "$comment"} ]} } },
    { $unwind: '$share' },
    { $lookup: { from: "users", localField: "share.userid", foreignField: "_id", as: 
    "users" }},
    { $group: {
        _id: "$_id",
        share: { $push: { $mergeObjects: ['$share', { $arrayElemAt: [ "$users", 0 ] } 
    ]}},
        data: { $first: "$$ROOT" }
    }},
    { $replaceRoot: { newRoot: { $mergeObjects: ['$data', { share: "$share"} ]} } },
    { $project: { users: 0 }}
    )
    

    您将获得输出,根据您的要求更改项目聚合中的添加/删除字段名称

    【讨论】:

      【解决方案2】:

      请检查:

          db.user_posts.aggregate([{ $match: { _id: ObjectId("5d519f861c9d4400005ebd1b") } }, {
          $lookup:
          {
              from: "user_profile",
              let: { userIdToBeCompared: "$userid", like: '$like', comment: '$comment', share: '$share' },
              pipeline: [
                  {
                      $match:
                      {
                          $expr:
                          {
      
                              $or:
                                  [
                                      { $eq: ["$_id", "$$userIdToBeCompared"] },
                                      { $in: ["$_id", "$$like.userid"] },
                                      { $in: ["$_id", "$$comment.userid"] },
                                      { $in: ["$_id", "$$share.userid"] }
                                  ]
                          }
                      }
                  }
      
              ],
              as: "data"
          }
      }])
      

      好吧,您的需求中有太​​多事情要做,而对于您当前的数据结构,从您的数据库层实现您的所有需求可能不是一件容易的事情和一个好主意,所以在这里最终响应 data 将拥有满足您需求的所有映射,将其添加到您的代码中,并根据用户 ID 为每个部分获取所需的详细信息,就我所尝试的而言,我认为这将是实现的理想方案!

      【讨论】:

      • @Ramesh :请尝试这个并根据您的发现进行重构,并随时添加内容,我可以进一步增强它!
      • 兄弟我得到了输出,但它与我的预期输出不同。像这样的输出,所有 user_posts 用户 ID 与 user_profile 集合 _id 的匹配并获得匹配的 user_profile _id 的详细信息显示在单独的数据数组中。我尝试使用 $project 聚合来显示用户名、喜欢的照片文件、评论、共享数组,但它不起作用
      • @RameshReddy :是的,准确地遍历所有字段并根据匹配键获取所需的详细信息在这种情况下通过 mongoDB 并不容易,因为它可以通过代码轻松完成,您可以尝试一下吗你的目的,同时我肯定会努力,如果有任何可行的解决方案,我会更新..
      • 兄弟根据我的预期输出的任何其他解决方案。
      • @RameshReddy :不,你想要的 o/p 必须通过代码来实现,通过 DB 实现它很乏味,我已经尝试了几种方法,或者另一种被卡住了;这里的东西太多了,或者您可以为每个阶段设置多个 $facet 阶段并将结果合并到代码中,这也不能满足您在数据库查询中的要求。
      猜你喜欢
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 1970-01-01
      • 2013-03-15
      • 1970-01-01
      • 2015-07-22
      • 1970-01-01
      • 2016-08-22
      相关资源
      最近更新 更多