我应该如何正确使用与猫鼬一起填充?

Edu*_*ván 6 javascript populate mongoose node.js

我正在学习一些节点,并一直在尝试使用猫鼬.目前,我的目标是学习如何使用填充.

我有一个projects定义并milestone要求:

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")();
Run Code Online (Sandbox Code Playgroud)

然后我在以下的某个时候这样做projects.js:

Project.find(query, {}, {sort: {_id: -1}},
    function (error, results) {
        callback(results);
    }
).populate("milestones");
Run Code Online (Sandbox Code Playgroud)

我如何填充里程碑?


这是project来自mongo 的数据:

{
    "title": "sitename",
    "description": "online thing",
    "creation_date": {
        "$date": "2013-07-11T19:45:42.139Z"
    },
    "_id": {
        "$oid": "51df0b66dbdd7c4f14000001"
    },
    "milestones": [],
    "milestone_ids": [],
    "__v": 0
}
Run Code Online (Sandbox Code Playgroud)

而这个milestone基本上与项目有关:

{
    "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
}
Run Code Online (Sandbox Code Playgroud)

此外,这是里程碑架构:

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);
Run Code Online (Sandbox Code Playgroud)

Pet*_*ons 13

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);
});
Run Code Online (Sandbox Code Playgroud)

Or a little more readable:

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

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 告诉mongoose你完成了配置查询并且mongoose发出了DB命令