0

I have two collections 1) user_posts 2)user_profile. find the below collection data for your reference.

1) user_posts collection

_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 collection

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

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

Now i tried to get the profile details from user_profile in lambda function. but i didn't get the details. find the below lambda function code.

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)

but i didn't get the output. i need output like this below.

_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 : " "

can you please help me the solutions. Thanks in advance.

0

2 Answers 2

0

Please check this:

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 }}
)

you will get output, changes add/remove fields name in project aggregation as per your requirement

Sign up to request clarification or add additional context in comments.

Comments

0

Please check this :

    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"
    }
}])

Ok there are way too many things has to happen in your requirement and with your current data structure it might not be an easy thing & a good idea to implement all your needs from your DB layer, So over here final response data will have all the mappings for your needs, get it to your code and fetch the needed details to each section based on userid, as of what I've tried I thought that would be ideal scenario to implement !!

5 Comments

@Ramesh : Please try this and refactor with your findings and feel free to add things, I can take a look to enhance it further !!
bro i get the output but it is not similar to my expected output. output like this, all user_posts userid's matching with user_profile collection _id's and get matched user_profile _id's details display in separate data array. I tried to used $project aggregation to display the username, photo fileds in like, comment, share arrays but it is not working
@RameshReddy : Yes exactly iterate thru all the fields and fetch the needed details based on matching keys is not that easy in this case thru mongoDB, Since it could be easily done by code can you try it at your end, meanwhile I would certainly work on it & will update if any feasible solution is achieved..
Bro any other solutions according my expected output.
@RameshReddy : nope your desired o/p has to be achieved thru code, doing it thru DB is tedious, I've tried couple of ways someway or the other getting stuck i.e; too many thing here, Or you can've multiple $facet stages for each and merge the results in the code, that as well doesn't serve your requirement in DB query.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.