f w h

Populating Multiple Fields and Levels with Mongoose

Mongoose, the popular MongoDB library for NodeJS is incredibly robust and relatively easy to pick up. Its documentation, however leaves a little to be desired.

To attain functionality similar to join functionality present in relational databases, Mongoose provides a method called populate(). Used in conjunction with the ref schema property, data can be pulled in from other documents in place of an id. The process is fairly straightforward. However, what Automattic’s documentation doesn’t explain is how to populate multiple paths, and the documentation for multiple levels leaves much to be desired.

The documentation does point out that chaining multiple populate functions won’t work. How, then can this be done? Multiple paths may be populated by creating a space-separated list. Note the emphasis, because comma-separated lists do not work. By way of example:


// Doesn't work - will only populate 'friends'
Users.findOne({/* query here */})
.populate('address')
.populate('friends');

// Works
Users.findOne({/* query here */})
.populate('address friends');

Now, what if we wanted to populate the friends’ addresses? As explained in the docs, you would nest another populate by passing an object to the method, and adding another populate as a property. That sounds incredibly confusing, I’m sure, but here’s what I mean.


// This time, we're not passing a string, but an object to populate()
Users.findOne({/* query here */})
.populate({
  path: 'address friends', // The string we passed in before
  populate: {
    path: 'address' // This will populate the friends' addresses
  }
});