Search code examples
node.js

How to access Subdocuments with reference in Mongoose?


I want to acess Subdocument using Mongoose

This is my conversations schema :

const Conversations = new mongoose.Schema({

    userOneId: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    userTwoId: {
         type: Schema.Types.ObjectId,
        ref: 'User'
    }

This is my User Model Schema:

....
  conversations: [{ type: Schema.Types.ObjectId, ref: 'Conversations' }]
});

After inserted i get this:

{
    "_id": {
        "$oid": "5a6fa114ffc53523705d52af"
    },
    "created_at": {
        "$date": "2018-01-29T22:32:52.930Z"
    },
    "messages": [],
    "__v": 0
}

I have inserted this :

 "conversations": [
        {
            "$oid": "5a6fa14a5562572a541bacae"
        },

I have put this:

  Object.assign(conversation, {userOneId: user._id});
    Object.assign(conversation, {userTwoId: friend._id});

I want to acess the "$oid": "5a6fa114ffc53523705d52af" to get the userOneId and userTwoId information.


Solution

  • you need to use populate.

    Basically, inside the "conversations" property in a user object, you only have the ObjectId of conversations, not the entire mongoose object. when you're querying the database for a user/users, you have to tell mongoose that you want it to replace the ObjectIds with the entire objects.

    //lets say you have a variable, userId, inside of which you have the id
    //of a user, and now you're querying the database for that user
    
    User.findById(userId).populate("conversations")
    .exec(function(err, foundUser){
         if(err){
             console.log(err):
         } else {
             console.log(foundUser.conversations);
         }
    });
    

    if you were to run the code above with an actual user _id, then (unless you got an error) you would have printed in your console rather than an array of conversation mongoose ids, an array of conversation mongoose objects. the entire things.

    if you only wanted the conversations to have two properties, userOneId and userTwoId, then combine populate with select. instead of

    .populate("conversations")
    

    use

    .populate({
         path: "conversations",
         select: "userOneId userTwoId"
    })