var mongoose =require('mongoose'), Schema =mongoose.Schemavar personSchema =Schema({ _id : Number, name : String, age : Number, stories : [{ type:Schema.Types.ObjectId, ref:'Story' }]});var storySchema =Schema({ _creator : { type: Number, ref:'Person' }, title : String, fans : [{ type: Number, ref:'Person' }]});var Story =mongoose.model('Story', storySchema);var Person =mongoose.model('Person', personSchema);
到目前为止,我们已经创建了两个模型。我们的Person 模型有stories字段设置为ObjectIds数组。ref 选项告诉Mongoose哪个模型中中使用 population,在我们的案例 Story 模型。所有的_ids我们存储的必须是 Story 模型的_ids。我们还声明 Story 的_creator属性作为数字型,和 _id类型相同用在personSchema中。这是非常重要的匹配 _id类型到 ref 类型。
注:ObjectId,Number,String,和Buffer都是作为refs有效的类型。
Saving refs
引用其他文件保存的工作方式相同,通常保存属性,只是分配的_id值:
var aaron =newPerson({ _id:0, name:'Aaron', age:100 });aaron.save(function (err) {if (err) returnhandleError(err);var story1 =newStory({ title:"Once upon a timex.", _creator:aaron._id // assign the _id from the person });story1.save(function (err) {if (err) returnhandleError(err);// thats it! });});
Population
到目前为止,我们还没有做任何不同的事情。我们只是创造了一个 Person 和一个 Story 。现在让我们使用查询生成器看一下填充story的_creator。
Story.findOne({ title:'Once upon a timex.' }).populate('_creator').exec(function (err, story) {if (err) returnhandleError(err);console.log('The creator is %s',story._creator.name);// prints "The creator is Aaron"});
Story.findOne({ title: /timex/i }).populate('_creator','name') // only return the Persons name.exec(function (err, story) {if (err) returnhandleError(err);console.log('The creator is %s',story._creator.name);// prints "The creator is Aaron"console.log('The creators age is %s',story._creator.age);// prints "The creators age is null'})`
Populating multiple paths
如果我们想在同一时间填充多个路径呢?
Story.find(...).populate('fans _creator') // space delimited path names.exec()
Person.findOne({ name:'Aaron' }).populate('stories') // only works if we pushed refs to children.exec(function (err, person) {if (err) returnhandleError(err);console.log(person);})
User.findOne({ name:'Val' }).populate({ path:'friends',// Get friends of friends - populate the 'friends' array for every friend populate: { path:'friends' } });
Populating整个数据库
让我们说,你有一个代表事件的模式,和一个代表对话的模式。每个事件都有一个相应的会话线程。
var eventSchema =newSchema({ name: String,// The id of the corresponding conversation// Notice there's no ref here! conversation: ObjectId});var conversationSchema =newSchema({ numMessages: Number});
var PersonSchema =newSchema({ name: String, band: String});var BandSchema =newSchema({ name: String});BandSchema.virtual('members', { ref:'Person',// The model to use localField:'name',// Find people where `localField` foreignField:'band'// is equal to `foreignField`});var Person =mongoose.model('Person', personSchema);var Band =mongoose.model('Band', bandSchema);/** * Suppose you have 2 bands: "Guns N' Roses" and "Motley Crue" * And 4 people: "Axl Rose" and "Slash" with "Guns N' Roses", and * "Vince Neil" and "Nikki Sixx" with "Motley Crue" */Band.find({}).populate('members').exec(function(error, bands) {/* `bands.members` is now an array of instances of `Person` */});`