6 Mongoose is a MongoDB object modeling tool designed to work in an asynchronous
9 Defining a model is as easy as:
12 var Comments = new Schema({
18 var BlogPost = new Schema({
23 , comments : [Comments]
30 mongoose.model('BlogPost', BlogPost);
35 The recommended way is through the excellent NPM:
38 $ npm install mongoose
41 Otherwise, you can check it in your repository and then expose it:
44 $ git clone git@github.com:LearnBoost/mongoose.git support/mongoose/
48 require.paths.unshift('support/mongoose/lib')
51 Then you can `require` it:
57 ## Connecting to MongoDB
59 First, we need to define a connection. If your app uses only one database, you
60 should use `mongose.connect`. If you need to create additional connections, use
61 `mongoose.createConnection`.
63 Both `connect` and `createConnection` take a `mongodb://` URI, or the parameters
64 `host, database, port`.
67 var mongoose = require('mongoose');
69 mongoose.connect('mongodb://localhost/my_database');
72 Once connected, the `open` event is fired on the `Connection` instance. If
73 you're using `mongoose.connect`, the `Connection` is `mongoose.connection`.
74 Otherwise, `mongoose.createConnection` return value is a `Connection`.
76 **Important!** Mongoose buffers all the commands until it's connected to the
77 database. This means that you don't have to wait until it connects to MongoDB
78 in order to define models, run queries, etc.
82 Models are defined through the `Schema` interface.
85 var Schema = mongoose.Schema
86 , ObjectId = Schema.ObjectId;
88 var BlogPost = new Schema({
96 Aside from defining the structure of your documents and the types of data you're
97 storing, a Schema handles the definition of:
99 * Validators (async and sync)
109 The following example shows some of these features:
112 var Comment = new Schema({
113 name : { type: String, default: 'hahaha' }
114 , age : { type: Number, min: 18, index: true }
115 , bio : { type: String, match: /[a-z]/ }
116 , date : { type: Date, default: Date.now }
120 Comment.path('name').set(function (v) {
121 return v.capitalize();
125 Comment.pre('save', function (next) {
126 notify(this.get('email'));
131 Take a look at the example in `examples/schema.js` for an end-to-end example of
132 (almost) all the functionality available.
136 Once we define a model through `mongoose.model('ModelName', mySchema)`, we can
137 access it through the same function
140 var myModel = mongoose.model('ModelName');
143 We can then instantiate it, and save it:
146 var instance = new myModel();
147 instance.my.key = 'hello';
148 instance.save(function (err) {
153 Or we can find documents from the same collection
156 myModel.find({}, function (err, docs) {
161 You can also `findOne`, `findById`, `update`, etc. For more details check out
164 ## Embedded Documents
166 In the first example snippet, we defined a key in the Schema that looks like:
172 Where `Comments` is a `Schema` we created. This means that creating embedded
173 documents is as simple as:
177 var BlogPost = mongoose.model('BlogPost');
179 // create a blog post
180 var post = new BlogPost();
183 post.comments.push({ title: 'My comment' });
185 post.save(function (err) {
186 if (!err) console.log('Success!');
190 The same goes for removing them:
193 BlogPost.findById(myId, function (err, post) {
195 post.comments[0].remove();
196 post.save(function (err) {
203 Embedded documents enjoy all the same features as your models. Defaults,
204 validators, middleware. Whenever an error occurs, it's bubbled to the `save()`
205 error callback, so error handling is a snap!
207 Mongoose interacts with your embedded documents in arrays _atomically_, out of
212 Middleware is one of the most exciting features about Mongoose 1.0. Middleware
213 takes away all the pain of nested callbacks.
215 Middleware are defined at the Schema level and are applied when the methods
216 `init` (when a document is initialized with data from MongoDB), `save` (when
217 a document or embedded document is saved).
219 There's two types of middleware:
222 Serial middleware are defined like:
225 .pre(method, function (next, methodArg1, methodArg2, ...) {
230 They're executed one after the other, when each middleware calls `next`.
232 You can also intercept the `method`'s incoming arguments via your middleware --
233 notice `methodArg1`, `methodArg2`, etc in the `pre` definition above. See
234 section "Intercepting and mutating method arguments" below.
238 Parallel middleware offer more fine-grained flow control, and are defined
242 .pre(method, true, function (next, done, methodArg1, methodArg2) {
247 Parallel middleware can `next()` immediately, but the final argument will be
248 called when all the parallel middleware have called `done()`.
252 If any middleware calls `next` or `done` with an `Error` instance, the flow is
253 interrupted, and the error is passed to the function passed as an argument.
258 schema.pre('save', function (next) {
259 // something goes wrong
260 next(new Error('something went wrong'));
265 myModel.save(function (err) {
266 // err can come from a middleware
270 ### Intercepting and mutating method arguments
272 You can intercept method arguments via middleware.
274 For example, this would allow you to broadcast changes about your Documents
275 every time someone `set`s a path in your Document to a new value:
278 schema.pre('set', function (next, path, val, typel) {
279 // `this` is the current Document
280 this.emit('set', path, val);
282 // Pass control to the next pre
287 Moreover, you can mutate the incoming `method` arguments so that subsequent
288 middleware see different values for those arguments. To do so, just pass the
289 new values to `next`:
292 .pre(method, function firstPre (next, methodArg1, methodArg2) {
294 next("altered-" + methodArg1.toString(), methodArg2);
295 }) // pre declaration is chainable
296 .pre(method, function secondPre (next, methodArg1, methodArg2) {
297 console.log(methodArg1);
298 // => 'altered-originalValOfMethodArg1'
300 console.log(methodArg2);
301 // => 'originalValOfMethodArg2'
303 // Passing no arguments to `next` automatically passes along the current argument values
304 // i.e., the following `next()` is equivalent to `next(methodArg1, methodArg2)`
305 // and also equivalent to, with the example method arg
306 // values, `next('altered-originalValOfMethodArg1', 'originalValOfMethodArg2')`
313 You can find the [Dox](http://github.com/visionmedia/dox) generated API docs at
314 [http://mongoosejs.com](http://mongoosejs.com).
318 Please subscribe to the Google Groups [mailing
319 list](http://groups.google.com/group/mongoose-orm/boxsubscribe).
323 The following plugins are currently available for use with mongoose:
325 - [mongoose-types](https://github.com/bnoguchi/mongoose-types) - Adds
326 several additional types (e.g., Email) that you can use in your
328 - [mongoose-auth](https://github.com/bnoguchi/mongoose-auth) - A drop in
329 solution for your auth needs. Currently supports Password, Facebook,
330 Twitter, Github, and more.
331 - [mongoose-dbref](https://github.com/goulash1971/mongoose-dbref) - Adds DBRef support
332 - [mongoose-joins](https://github.com/goulash1971/mongoose-joins) - Adds simple join support
334 ## Contributing to Mongoose
336 ### Cloning the repository
338 Make a fork of `mongoose`, then clone it in your computer. The `master` branch
339 contains the current stable release, and the `develop` branch the next upcoming
342 If `master` is at `1.0`, `develop` will contain the upcoming `1.1` (or `2.0` if
343 the `1` branch is nearing its completion).
347 - Please write inline documentation for new methods or class members.
348 - Please write tests and make sure your tests pass.
349 - Before starting to write code, look for existing tickets or create one for
350 your specifc issue (unless you're addressing something that's clearly broken).
351 That way you avoid working on something that might not be of interest or that
352 has been addressed already in a different branch.
356 - Guillermo Rauch - guillermo@learnboost.com - [Guille](http://github.com/guille)
357 - Nathan White - [nw](http://github.com/nw/)
358 - Brian Noguchi - [bnoguchi](https://github.com/bnoguchi)
359 - Aaron Heckmann - [aheckmann](https://github.com/aheckmann)
363 Copyright (c) 2010 LearnBoost <dev@learnboost.com>
365 Permission is hereby granted, free of charge, to any person obtaining
366 a copy of this software and associated documentation files (the
367 'Software'), to deal in the Software without restriction, including
368 without limitation the rights to use, copy, modify, merge, publish,
369 distribute, sublicense, and/or sell copies of the Software, and to
370 permit persons to whom the Software is furnished to do so, subject to
371 the following conditions:
373 The above copyright notice and this permission notice shall be
374 included in all copies or substantial portions of the Software.
376 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
377 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
378 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
379 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
380 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
381 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
382 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.