How should I properly use populate with mongoose?

与世无争的帅哥 提交于 2019-12-18 04:54:21

问题


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);

回答1:


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


来源:https://stackoverflow.com/questions/17598712/how-should-i-properly-use-populate-with-mongoose

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!