Search code examples
node.jsmongodbmongoosemongoose-populate

Populate collection inside another collection mongoDB with mongoose nodejs


I'm trying to get all the information from a particular user. I can already populate the collections that it contains, but I'm unable to populate a very important attribute within these collections, the user. I have the following code that reprints the models and the code that I have already done for the query. I also present a result of what I can get and an example of what I want. Thank you for helping me.

I have the following templates in Mongoose:

const schema = new Schema(
{
   .....
    nameEvent:
    {
        type: String,
        required: true
    },
    owner:
    {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    },
    invited:
    [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    }],
    participants:
    [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    }]
});

module.exports = mongoose.model('Meeting', schema);

And:

const schema = new Schema(
{
    name:
    {
        type: String,
        required: true
    },
   ...
    photoPath:
    {
        type: String,
        required: true
    },
    qrcodePath:
    {
        type: String,
        required: false
    },
    receiveInvites:
    {
        type: Boolean,
        required: true
    },
    invited:
    [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Meeting'
    }],
    participating:
    [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Meeting'
    }],
    owned:
    [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Meeting'
    }]
});

module.exports = mongoose.model('User', schema);

Now I want to load all user information and populate some fields that I need.

When I run the following code:

exports.getByid = async(id) =>
{
    const res = await User.findById(id, '_id name photoPath invited participating owned friends')
    .populate('invited', 'nameEvent owner date time numberPlayer participants')
    .populate('participating', 'nameEvent owner date time numberPlayer participants')
    .populate('owned', 'nameEvent owner date time numberPlayer participants');
    return res;
}

I get the following JSON:

"result": {
  "invited": [],
  "participating": [
    {
      "participants": [
        "5c8a9e46ba60372df4483d2f"
      ],
      "_id": "5c8a9e5dba60372df4483d30",
      "nameEvent": "terças",
      "numberPlayer": 10,
      "date": "19/03/2019",
      "time": "20:00",
      "owner": "5c8a9e46ba60372df4483d2f"
    },
    {
      "participants": [
        "5c8a9e46ba60372df4483d2f"
      ],
      "_id": "5c8aad5eba60372df4483d34",
      "nameEvent": "quintas",
      "numberPlayer": 3,
      "date": "21/03/2019",
      "time": "15:00",
      "owner": "5c8a9e46ba60372df4483d2f"
    }
  ], ....
}

But I want more info about the owner User (name and photoPath).

How do I populate these additional fields?

This is what I'm looking for:

{
  "participants": [
    "5c8a9e46ba60372df4483d2f"
  ],
  "_id": "5c8aad5eba60372df4483d34",
  "nameEvent": "quintas",
  "numberPlayer": 3,
  "date": "21/03/2019",
  "time": "15:00",
  "owner": {
    "id":"5c8a9e46ba60372df4483d2f",
    "name":"name User",
    "photoPath": "photoPath.jpg"
  }
}

Solution

  • You're not asking for those fields to be populated in your code. If you want all of the fields back from an object, try something like this:

    exports.getByid = async (id) => {
      const res = await User.findById(id, '_id name photoPath invited participating owned friends')
        .populate({ path: 'invited' })
        .populate({ path: 'participating' })
        .populate({ 
            path: 'owned',
            populate: { path: 'owner' }
        });
      return res;
    }
    

    Take a look a deep population from the Mongoose docs.