Mongoose – 使用.populate访问嵌套对象

模式定义

Team.js

var TeamSchema = new Schema({ // Team Name. name: String, lead: String, students :type: [{ block : Number, status : String, student : { type: Schema.ObjectId, ref: 'Student' }] }); 

Student.js

 var StudentSchema = new Schema({ name: String, rollNo : Number, class : Number }); 

我如何填充“学生”获得输出,如下所示:

球队

 { "__v": 1, "_id": "5252875356f64d6d28000001", "students": [ { "__v": 1, "_id": "5252875a56f64d6d28000002", block : 1, status : joined, "student": { "name": Sumeeth "rollNo" : 2 "class" : 5 } }, { "__v": 1, "_id": "5252875a56f64d6d28000003", block : 1, status : joined, "student": { "name": Sabari "rollNo" : 3 "class" : 4 } } ], "lead": "Ratha", } 

这是我用来获取使用Mongoose的文档的JS:

 Team.findOne({ _id: req.team._id }) .populate('students') .select('students') .exec(function(err, team) { console.log(team); var options = { path: 'students.student', model: 'Student' }; Student.populate(team.students,options,function(err, students) { console.log(students); if (err) { console.log(students); res.send(500, { message: 'Unable to query the team!' }); } else { res.send(200, students); } }); }); 

在我的控制台输出中,我得到以下内容:

 { _id: 53aa434858f760900b3f2246, students [ { block : 1 status: 'joined' _id: 53aa436b58f760900b3f2249 }, { block : 1 status: 'joined' _id: 53aa436b58f760900b3f2250 }] } 

预期的产出是:

  { _id: 53aa434858f760900b3f2246, students [ { block : 1 status: 'joined' student :{ "name": Sumeeth "rollNo" : 2 "class" : 5 } }, { block : 1 status: 'joined' student :{ "name": Sabari "rollNo" : 3 "class" : 4 } } ] } 

有人请帮我,我错了。 我应该如何利用.populate,这样我就可以得到整个学生对象,而不仅仅是它的id。

参考: 在mongoose中填充嵌套数组

这里是你想要的简化版本。

基本数据的设置,首先是“学生”:

 { "_id" : ObjectId("53aa90c83ad07196636e175f"), "name" : "Bill", "rollNo" : 1, "class" : 12 }, { "_id" : ObjectId("53aa90e93ad07196636e1761"), "name" : "Ted", "rollNo" : 2, "class" : 12 } 

然后是“团队”集合:

 { "_id" : ObjectId("53aa91b63ad07196636e1762"), "name" : "team1", "lead" : "me", "students" : [ { "block" : 1, "status" : "Y", "student" : ObjectId("53aa90c83ad07196636e175f") }, { "block" : 2, "status" : "N", "student" : ObjectId("53aa90e93ad07196636e1761") } ] } 

这是你如何做到的:

 var async = require('async'), mongoose = require('mongoose'); Schema = mongoose.Schema; mongoose.connect('mongodb://localhost/team'); var teamSchema = new Schema({ name: String, lead: String, students: [{ block: Number, status: String, student: { type: Schema.ObjectId, ref: 'Student' } }] }); var studentSchema = new Schema({ name: String, rollNo: Number, class: Number }); var Team = mongoose.model( "Team", teamSchema ); var Student = mongoose.model( "Student", studentSchema ); Team.findById("53aa91b63ad07196636e1762") .select('students') .exec(function(err, team) { console.log( team ); async.forEach(team.students, function(student,callback) { Student.populate( student, { "path": "student" }, function(err,output) { if (err) throw err; callback(); } ); },function(err) { console.log( JSON.stringify( team, undefined, 4 ) ); }); }); 

它给你的结果:

 { "_id": "53aa91b63ad07196636e1762", "students": [ { "block": 1, "status": "Y", "student": { "_id": "53aa90c83ad07196636e175f", "name": "Bill", "rollNo": 1, "class": 12 } }, { "block": 2, "status": "N", "student": { "_id": "53aa90e93ad07196636e1761", "name": "Ted", "rollNo": 2, "class": 12 } } ] } 

你真的不需要“asynchronous”模块,但我只是“习惯”,因为它是。 它不“阻止”,所以我认为它更好。

正如你所看到的,你最初的.populate()调用不会做任何事情,因为它希望从一个数组input中的“ .populate() ”值中“键入”这个“严格地说”不是“key “包含”外键“的”学生“。

我在这里最近的回答中确实覆盖了这一点 ,可能并不完全针对你的情况。 看来你的search没有出现正确的“相同的答案”(虽然不完全)为你从中提取参考。

你正在超越它。 让mongoose做你的工作。

 Team.findOne({ _id: req.team._id }) .populate({path:'students'}) .exec(function(err, team) { console.log(team); }); 

这将把学生作为文件而不仅仅是ID。

我一直面临同样的问题。 我使用这个代码来拯救我:

 Team.findOne({_id: req.team._id}) .populate({ path: "students.student"}) .exec(function(err, team) { console.log(team); });