From 686106d544ecc3b6ffd4db2b665d3bc879a58d8c Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 24 Sep 2012 16:22:07 -0400 Subject: ok --- node_modules/mongoose/docs/populate.md | 166 +++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 node_modules/mongoose/docs/populate.md (limited to 'node_modules/mongoose/docs/populate.md') diff --git a/node_modules/mongoose/docs/populate.md b/node_modules/mongoose/docs/populate.md new file mode 100644 index 0000000..d2ad207 --- /dev/null +++ b/node_modules/mongoose/docs/populate.md @@ -0,0 +1,166 @@ +Populate - DBRef-like behavior (experimental) +============================================= + +`ObjectIds` can now refer to another document in a +collection within our database and be populated when +querying. An example is helpful: + + var mongoose = require('mongoose') + , Schema = mongoose.Schema + + var PersonSchema = new Schema({ + name : String + , age : Number + , stories : [{ type: Schema.ObjectId, ref: 'Story' }] + }); + + var StorySchema = new Schema({ + _creator : { type: Schema.ObjectId, ref: 'Person' } + , title : String + , fans : [{ type: Schema.ObjectId, ref: 'Person' }] + }); + + var Story = mongoose.model('Story', StorySchema); + var Person = mongoose.model('Person', PersonSchema); + +So far we've created two models. Our `Person` model has it's `stories` field +set to an array of `ObjectId`s. The `ref` option is what tells Mongoose in which +model to look, in our case the `Story` model. All `_id`s we +store here must be document `_id`s from the `Story` model. We also added +a `_creator` `ObjectId` to our `Story` schema which refers to a single `Person`. + +## Saving a ref (to the parent) + +Below you can see how we "save" a ref in 'story1' back to the _creator. This +is usually all you need to do. + + + var aaron = new Person({ name: 'Aaron', age: 100 }); + + aaron.save(function (err) { + if (err) ... + + var story1 = new Story({ + title: "A man who cooked Nintendo" + , _creator: aaron._id + }); + + story1.save(function (err) { + if (err) ... + }); + }) + +## Populating the refs (to the parent) + +So far we haven't done anything special. We've merely created a `Person` and +a `Story`. Now let's take a look at populating our story's `_creator`: + + Story + .findOne({ title: /Nintendo/i }) + .populate('_creator') // <-- + .run(function (err, story) { + if (err) .. + console.log('The creator is %s', story._creator.name); + // prints "The creator is Aaron" + }) + +Yup that's it. We've just queried for a `Story` with the term Nintendo in it's +title and also queried the `Person` collection for the story's creator. Nice! + +Arrays of `ObjectId` refs work the same way. Just call the `populate` method on the query and +an array of documents will be returned in place of the `ObjectId`s. + +What if we only want a few specific fields returned for the query? This can +be accomplished by passing an array of field names to the `populate` method: + + Story + .findOne({ title: /Nintendo/i }) + .populate('_creator', ['name']) // <-- only return the Persons name + .run(function (err, story) { + if (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' + }) + +Now this is much better. The only property of the creator we are using +is the `name` so we only returned that field from the db. Efficiency FTW! + + +## References to the children + +You may find however, if you use the `aaron` object, you are unable to get +a list of the `stories`. This is because no `story` objects were ever 'pushed' +on to `aaron.stories`. + +There are two perspectives to this story. First, it's nice to have aaron know +which are his stories. + + aaron.stories.push(story1); + aaron.save(); + +This allows you do a find & populate like: + + Person + .findOne({ name: 'Aaron' }) + .populate('stories') // <-- only works if you pushed refs to children + .run(function (err, person) { + if (err) .. + + console.log('JSON for person is: ', person); + + }) + +However, it is debatable that you really want two sets of pointers as they +may get out of sync. So you could instead merely find() the documents you +are interested in. + + Story + .find({ _creator: aaron._id }) + .populate('_creator') // <-- not really necessary + .run(function (err, stories) { + if (err) .. + + console.log('The stories JSON is an array: ', stoires); + }) + + + + +## Updating + +Now that we have a story we realized that the `_creator` was incorrect. We can +update `ObjectId` refs the same as any other property through the magic of Mongooses +internal casting: + + var guille = new Person({ name: 'Guillermo' }); + guille.save(function (err) { + if (err) .. + + story._creator = guille; // or guille._id + + story.save(function (err) { + if (err) .. + + Story + .findOne({ title: /Nintendo/i }) + .populate('_creator', ['name']) + .run(function (err, story) { + if (err) .. + + console.log('The creator is %s', story._creator.name) + // prints "The creator is Guillermo" + }) + + }) + }) + +### Note: + +The documents returned from calling `populate` become fully functional, +`remove`able, `save`able documents. Do not confuse them with embedded +docs. Take caution when calling its `remove` method because +you'll be removing it from the database, not just the array. -- cgit v1.2.3-70-g09d2