Search code examples
javascriptnode.jsmongodbmongoosemongoose-populate

How to populate nested entity in Mongoose?


I have such models:

const UserSchema = new mongoose.Schema({
  name: String,
  workspaces: [
    {
      workspace: {
        type: mongoose.Schema.ObjectId,
      },
      owner: Boolean
    }
  ]
});

const WorkspaceSchema = new mongoose.Schema({
  title: String,
  description: String 
});

I want to populate the User record like this:

{
  name: "John",
  workspaces: [{
    workspace: {
      title: "First space",
      description: "About space#1"
    },
    owner: true
  }, {
    workspace: {
      title: "Second space",
      description: "About space#2"
    },
    owner: false
  }]
}

I tried to do this via populate method:

const user = await User
  .findOne(query)
  .populate({
    path: 'workspaces',
    populate: {
      path: 'workspace',
      model: 'Workspace'
    }
  });

And it's not correct. I searched for case like this, but didn't find anything similar. All another examples doesn't includes property like my boolean "owner".


Solution

  • I recommend you to add reference to workspace model at the user schema declaration:

     workspace: {
        type: mongoose.Schema.ObjectId,
        ref: "Workspace"
     }
    

    Also, you probably messed up with populate method, because the workspaces array does not contain references to external objects itself. You probably should use this method like this:

    const user = await User
      .findOne(query)
      .populate("workspaces.workspace");
    

    Or, if you need any other options, than path, then use with options object:

    const user = await User
      .findOne(query)
      .populate({
        path: "workspaces.workspace", ...
      });