MongoDB没有join, 但是有的时候我们需要引用其它collection的documents, 这个时候就需要populate了.
我们可以populate单个document, 多个document, plain object, multiple plain objects或query返回的全部object.
var mongoose = require('mongoose'); var Schema = mongoose.Schema; var personSchema = new Schema({ _id: Number, name: String, age: Number, stories: [{type: Schema.Types.ObjectId, ref: 'story'}] }); var storySchema = new 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);
目前为止我们创建了两个model. Person model有一个stories字段是以个ObjectId的集合. ref是告诉mongoose哪个model应该被popluate.
Story有一个_creator字段是Number类型的他是personSchema的Id
Saving ref
保存一个ref
var arron = new Person({_id:0, name: 'Aaron', age: 100}); arron.save(function(err){ if(err) return handleError(err); var story1 = new Story({ titile: 'Once upon a timex', _creator: arron._id //分配person的_id }); story1.save(function(err){ if(err) return handleError(err); }); });
Populate
填充story的_creator
Story .findOne({title: 'Once upon a timex'}) .populate('_creator') .exec(fucntion(err, story){ if(err) return handleError(err); console.log(story._creator.name) // Aaron });
Field selection
如果我们不想为story填充整个_creator 我们只想填充_creator的name怎么搞呢?
Story .findOne({ title: /timex/i }) .populate('_creator', 'name') // only return the Persons name .exec(function (err, story) { if (err) return handleError(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' })
一次填充多个paths
如果我们想一次填充多个path怎么过搞呢
Story .find(...) .populate('fans author') // space delimited path names .exec()
另一种写法
Story .find(...) .populate('fans') .populate('author') .exec()
按条件填充
Story .find(...) .populate({ path: 'fans', match: { age: { $gte: 21 }}, select: 'name -_id', options: { limit: 5 } }) .exec()