How should I properly use populate with mongoose?

javascript, mongoose, node.js, populate

Solution

You need to get the order right of defining query options then executing, and chainable APIs such as mongoose Query can't know what additional methods you might call AFTER the query fires. So when you pass the callback to `.find`, mongoose sends the query right away.

Pass a callback to `find`

- query defined by arguments to `find`

- since callback is there, query immediately executes and issues command to DB

- then `.populate` happens, but it has no effect as the query has already been sent to mongo

Here's what you need to do:

Project.find(query, {}, {
    sort: {
        _id: -1
    }
}).populate("milestones").exec(function (error, results) {
    callback(results);
});

Or a little more readable:

Project
    .find(query)
    .sort('-_id')
    .populate('milestones')
    .exec(function(error, results) {                  
        callback(results);
    });

Omit callback and use `.exec`

- query passed to `.find` creates query object with parameters

- additional chained calls to `.sort`, `.populate` etc further configure the query

- `.exec` tells mongoose you are done configuring the query and mongoose issues the DB command

Problem

I am learning some node and have been trying to use mongoose. Currently, my goal is to learn how to use populate. I have a `projects` definition and `milestone` require: ``` projectSchema = new mongoose.Schema({ id: String, title: String, description: String, owner: String, site: String, creation_date: Date, milestone_ids: Array, milestones: [{ type: mongoose.Schema.Types.ObjectId, ref: "Milestone" }] }) Project = mongoose.model("Project", projectSchema) milestones = require(__dirname + "/milestones.js")(); ``` Then I do this at some point in the `projects.js`: ``` Project.find(query, {}, {sort: {_id: -1}}, function (error, results) { callback(results); } ).populate("milestones"); ``` How do I populate the milestones? Here is the `project` data from mongo: ``` { "title": "sitename", "description": "online thing", "creation_date": { "$date": "2013-07-11T19:45:42.139Z" }, "_id": { "$oid": "51df0b66dbdd7c4f14000001" }, "milestones": [], "milestone_ids": [], "__v": 0 } ``` And this one is the `milestone` that is basically connected to the project: ``` { "title": "Proof of concept", "description": "Make it work.", "due_date": { "$date": "2013-07-11T19:46:38.535Z" }, "project_id": "51df0b66dbdd7c4f14000001", "_id": { "$oid": "51df0b9edbdd7c4f14000002" }, "__v": 0 } ``` Also, this is the milestone schema: ``` milestoneschema = new mongoose.Schema({ id: String, title: String, description: String, owner: String, site: String, due_date: Date, project_id: { type: String, ref: "Project" } }) Milestone = mongoose.model("Milestone", milestoneschema); ```

Original source