1
votes

i was reading mongoosejs documentations and get on populate method and populate with 'ref' is some kinda obscure to understand i also saw many stackoverflow questions , MDN but nobody spent much time to explain that

var personSchema = Schema({
_id: Schema.Types.ObjectId,
name: String,
 age: Number,
 stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

var storySchema = Schema({
 author: { type: Schema.Types.ObjectId, ref: 'Person' },
 title: String,
 fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
 });

 var Story = mongoose.model('Story', storySchema);
 var Person = mongoose.model('Person', personSchema);

so here is one example and the docs are saying that ref: references which model should we use, but in this case author has ref to person and it's type is objectId and how can it store whole schema (_id, name ,age,stories) and same on stories property, how can it store whole schema (in mongoose language 'document') .

Story.
findOne({ title: 'Casino Royale' }).
populate('author').
exec(function (err, story) {
if (err) return handleError(err);
console.log('The author is %s', story.author.name);
// prints "The author is Ian Fleming"
});

here as i analysed this code finds field of title in story model then it gets author property in story model too and then gets name from second schema. as code shows,author has referenced person model but as i admited it's type is objectId and how can it store whole schema (_id, name ,age,stories)

if someone can explain this in more details they will help many of guys who did not get it like me

1

1 Answers

2
votes

ref basically means that mongoose would store the ObjectId values and when you call populate using those ObjectIds would fetch and fill the documents for you. So in this case:

stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]

An ObjectId for the Story would be only stored in the Person stories array and when you call on populate('stories') mongoose would go and do another query to find and match all the ObjectId and return you the actual Stories objects.

So ref just tells mongoose that you want to store there a reference to another model and at some point you want to populate those and get the full blown model by that reference.

In a sense it is nothing more than a foreign key to another collection by which you fetch the actual document when populate is called.

Here is the code broken down:

Story.findOne({ title: 'Casino Royale' })  // <-- filter on title
  // once a story is found populate its `author` with full author document 
  // instead of the `ObjectId` stored by the `ref`
  .populate('author')
  // execute the current pipeline
  .exec(function (err, story) { // handle the resulting record
    if (err) return handleError(err);
      console.log('The author is %s', story.author.name);
    });

Hope this helps.