4

Example of a document inside post collection

{
    postId: '232323',
    byUser: 'userid1',
    post: 'This is my first post',
        commentsOnPost: [
            {
                commentId: '232323_8888',
                byUser: 'userid2',
            comment: 'Congrats',
                repliesOnPost: [
                    {
                        replyId: '232323_8888_66666',
                        byUser: 'userid1',
                    reply: 'Thanks',
                        likesOnReplyBy: ['userid1', 'userid5', 'userid3'],

                    },
                    {
                        replyId: '232323_8888_55555',
                        byUser: 'user2',
                    reply: 'Welcome',
                        likesOnReplyBy: ['userid6', 'userid8', 'userid9'],

                    }
                ]
            }
        ]
}

I want to query this post such a way so that wherever userid comes I want to replace it from below collection of matched userid.

[
 {
  userid:userid1,
  displayName:'Bob',
  profilePic:'https://example.com/bob_profile.png'
 },

 {
  userid:userid2,
  displayName:'Lorish',
  profilePic:'https://example.com/lorish_profile.png'
 }

.
.
.
.

]

Is this possible such query? or Do I need to do referencing at the time of inserting document. I don't want to replace userid one by one by performing many loop.

Expected Output

{
    postId:'232323',
    byUser: {
     userid:userid2,
     displayName:'Lorish',
     profilePic:'https://example.com/lorish_profile.png'
    }
    post:'This is my first post',
    commentsOnPost:[
        {
            commentId:'232323_8888',
            byUser: {
             userid:userid1,
             displayName:'Bob',
             profilePic:'https://example.com/lorish_profile.png'
            },
            comment:'Congrats',
            repliesOnPost:[
                {
                    replyId:'232323_8888_66666',
                    byUser: {
                      userid:userid1,
                      displayName:'Bob',
                      profilePic:'https://example.com/lorish_profile.png'
                    },
                    reply:'Thanks',
                    likesOnReplyBy:[
                    {
                         userid:userid6,
                         displayName:'Kiti',
                         profilePic:'https://example.com/lorish_profile.png'
                     },
                     {
                         userid:userid2,
                         displayName:'Lorish',
                         profilePic:'https://example.com/lorish_profile.png'
                     }

                  ],
                    
                },
                {
                    replyId:'232323_8888_55555',
                    byUser: {
                       userid:userid2,
                       displayName:'Lorish',
                       profilePic:'https://example.com/lorish_profile.png'
                     },
                    reply:'Welcome',
                    likesOnReplyBy:[
                        {
                         userid:userid5,
                         displayName:'Rahul',
                         profilePic:'https://example.com/lorish_profile.png'
                        }
                    ],
                    
                }
            ]
        }
    ]
}
Deepak
  • 145
  • 2
  • 9
  • Does this answer your question? [Referencing another schema in Mongoose](https://stackoverflow.com/questions/18001478/referencing-another-schema-in-mongoose) – jatinder bhola Jul 12 '21 at 05:11
  • 1
    I have tired it with mongoose driver, which you can follow using https://stackoverflow.com/a/18002078/1964336 or learn from mongodb docs https://docs.mongodb.com/manual/reference/database-references/ – jatinder bhola Jul 12 '21 at 05:15
  • I am not using mongoose. I am using NodeJS Native Driver for MongoDB – Deepak Jul 12 '21 at 05:15
  • you can use aggregation query, but it's long process. deconstruct comments & relies array, than lookup with user collection, again reconstruct replies and comments array. i would not recommend this way it will not perform well. there are 2 options: 1) get list of users, when comments and replies shows just take user info from that list, you can make it as key-value pair object to fetch easily by its userid. – turivishal Jul 12 '21 at 05:48
  • 2) while mongodb is nosql, in your case join is more expensive, so as per mongodb it is ok to store duplicate data but avoid joins if possible, so you can just store user info in comments and replies, you don't need to join from anywhere. – turivishal Jul 12 '21 at 05:48
  • I can store user info everywhere where userid comes, But what if post got older and user change his display name or profile pic!! it will show old name or profile pic. I think this is not ok. – Deepak Jul 12 '21 at 06:02
  • you can sync info after a particular time duration. – turivishal Jul 12 '21 at 07:45
  • @Deepak Could you share how the final result will look like – Jits Jul 15 '21 at 12:38
  • @Jits added expected output. – Deepak Jul 16 '21 at 14:45
  • 1
    You could use something like this. https://mongoplayground.net/p/CSsjYnON9Za. Using unwinds to add the user info into the specific structures and the grouping them again. However i think its just easier if you just made another query for the users and map that data. – Rubén Vega Jul 19 '21 at 11:02
  • @Ruby Vega I appreciate your work but its not working when comments or replies are empty. – Deepak Jul 19 '21 at 20:59
  • Could you add some examples of those fails? – Rubén Vega Jul 19 '21 at 23:10
  • Just take empty array for commentsOnPost or repliesOnComments. https://mongoplayground.net/p/KnjyWIb5Uzs – Deepak Jul 20 '21 at 04:45
  • You just have to add a statement in the $unwind stage to prserve null and empty values. https://mongoplayground.net/p/5_wlr02WjIh – Rubén Vega Jul 20 '21 at 10:47
  • @Ruben Vega Great !! It's working fine. Just want to know the performance issue. You said for mapping users after retrieving the data. I need to apply 3 loop with DB lookup for doing this. Is this ok? Which one should be best in this case? – Deepak Jul 20 '21 at 14:06
  • @Deepak I'm not an expert on performance fields.... However I think the best solution will depend on what you want. When doing that query the computational work will be on the server side of mongoDB. If you do both queries separately and merge them in your application, the work will be split. What is the best solution? as I said, it depends, a simple example: if that query is made from many mobile devices in your client application, maybe it is better to process it there. because each of the N devices will process it 1 time, instead of your server processing it N times. – Rubén Vega Jul 21 '21 at 12:17
  • Thanks! You can post your comments as a answer. I will accept that. – Deepak Jul 21 '21 at 19:21

0 Answers0