summaryrefslogtreecommitdiff
path: root/node_modules/mongoose/docs/populate.md
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2012-09-24 16:22:07 -0400
committerJules Laplace <jules@okfoc.us>2012-09-24 16:22:07 -0400
commit686106d544ecc3b6ffd4db2b665d3bc879a58d8c (patch)
treea5b5e50237cef70e12f0745371896e96f5f6d578 /node_modules/mongoose/docs/populate.md
ok
Diffstat (limited to 'node_modules/mongoose/docs/populate.md')
-rw-r--r--node_modules/mongoose/docs/populate.md166
1 files changed, 166 insertions, 0 deletions
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.