Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 345 lines (233 sloc) 11.844 kb
55b825b @rauchg Updated README and example
rauchg authored
1 ## What's Mongoose?
2
2d50d64 @aheckmann updated readme
aheckmann authored
3 Mongoose is a [MongoDB](http://www.mongodb.org/) object modeling tool designed to work in an asynchronous environment.
55b825b @rauchg Updated README and example
rauchg authored
4
5 Defining a model is as easy as:
6
39ad6b2 @afanasy Update README.md
afanasy authored
7 var Comment = new Schema({
2d50d64 @aheckmann updated readme
aheckmann authored
8 title : String
9 , body : String
10 , date : Date
11 });
12
13 var BlogPost = new Schema({
14 author : ObjectId
15 , title : String
16 , body : String
17 , buf : Buffer
18 , date : Date
39ad6b2 @afanasy Update README.md
afanasy authored
19 , comments : [Comment]
2d50d64 @aheckmann updated readme
aheckmann authored
20 , meta : {
21 votes : Number
22 , favs : Number
23 }
24 });
25
26 var Post = mongoose.model('BlogPost', BlogPost);
55b825b @rauchg Updated README and example
rauchg authored
27
c659395 @aheckmann docs; fix links
aheckmann authored
28 ## Documentation
29
30 [mongoosejs.com](http://mongoosejs.com/)
31
f7b0648 @rauchg Added installation section
rauchg authored
32 ## Installation
33
2c293e0 @aheckmann release 2.0.0
aheckmann authored
34 The recommended way is through the excellent [NPM](http://www.npmjs.org/):
f7b0648 @rauchg Added installation section
rauchg authored
35
2d50d64 @aheckmann updated readme
aheckmann authored
36 $ npm install mongoose
f7b0648 @rauchg Added installation section
rauchg authored
37
38 Otherwise, you can check it in your repository and then expose it:
39
2d50d64 @aheckmann updated readme
aheckmann authored
40 $ git clone git://github.com/LearnBoost/mongoose.git node_modules/mongoose/
41
a544842 @tricknotes fixed README
tricknotes authored
42 And install dependency modules written on `package.json`.
f7b0648 @rauchg Added installation section
rauchg authored
43
69ce567 Added syntax highlighting.
Tony authored
44 Then you can `require` it:
f7b0648 @rauchg Added installation section
rauchg authored
45
2d50d64 @aheckmann updated readme
aheckmann authored
46 require('mongoose')
f7b0648 @rauchg Added installation section
rauchg authored
47
bf7f1df @rauchg Reformated
rauchg authored
48 ## Connecting to MongoDB
55b825b @rauchg Updated README and example
rauchg authored
49
2d50d64 @aheckmann updated readme
aheckmann authored
50 First, we need to define a connection. If your app uses only one database, you should use `mongose.connect`. If you need to create additional connections, use `mongoose.createConnection`.
55b825b @rauchg Updated README and example
rauchg authored
51
2d50d64 @aheckmann updated readme
aheckmann authored
52 Both `connect` and `createConnection` take a `mongodb://` URI, or the parameters `host, database, port, options`.
55b825b @rauchg Updated README and example
rauchg authored
53
2d50d64 @aheckmann updated readme
aheckmann authored
54 var mongoose = require('mongoose');
55b825b @rauchg Updated README and example
rauchg authored
55
2d50d64 @aheckmann updated readme
aheckmann authored
56 mongoose.connect('mongodb://localhost/my_database');
55b825b @rauchg Updated README and example
rauchg authored
57
2d50d64 @aheckmann updated readme
aheckmann authored
58 Once connected, the `open` event is fired on the `Connection` instance. If you're using `mongoose.connect`, the `Connection` is `mongoose.connection`. Otherwise, `mongoose.createConnection` return value is a `Connection`.
55b825b @rauchg Updated README and example
rauchg authored
59
2d50d64 @aheckmann updated readme
aheckmann authored
60 **Important!** Mongoose buffers all the commands until it's connected to the database. This means that you don't have to wait until it connects to MongoDB in order to define models, run queries, etc.
55b825b @rauchg Updated README and example
rauchg authored
61
bf7f1df @rauchg Reformated
rauchg authored
62 ## Defining a Model
55b825b @rauchg Updated README and example
rauchg authored
63
64 Models are defined through the `Schema` interface.
65
2d50d64 @aheckmann updated readme
aheckmann authored
66 var Schema = mongoose.Schema
67 , ObjectId = Schema.ObjectId;
55b825b @rauchg Updated README and example
rauchg authored
68
2d50d64 @aheckmann updated readme
aheckmann authored
69 var BlogPost = new Schema({
70 author : ObjectId
71 , title : String
72 , body : String
73 , date : Date
74 });
55b825b @rauchg Updated README and example
rauchg authored
75
2d50d64 @aheckmann updated readme
aheckmann authored
76 Aside from defining the structure of your documents and the types of data you're storing, a Schema handles the definition of:
55b825b @rauchg Updated README and example
rauchg authored
77
2c293e0 @aheckmann release 2.0.0
aheckmann authored
78 * [Validators](http://mongoosejs.com/docs/validation.html) (async and sync)
c659395 @aheckmann docs; fix links
aheckmann authored
79 * [Defaults](http://mongoosejs.com/docs/api.html#schematype_SchemaType-default)
80 * [Getters](http://mongoosejs.com/docs/api.html#schematype_SchemaType-get)
81 * [Setters](http://mongoosejs.com/docs/api.html#schematype_SchemaType-set)
82 * [Indexes](http://mongoosejs.com/docs/guide.html#indexes)
2c293e0 @aheckmann release 2.0.0
aheckmann authored
83 * [Middleware](http://mongoosejs.com/docs/middleware.html)
c659395 @aheckmann docs; fix links
aheckmann authored
84 * [Methods](http://mongoosejs.com/docs/guide.html#methods) definition
85 * [Statics](http://mongoosejs.com/docs/guide.html#statics) definition
2c293e0 @aheckmann release 2.0.0
aheckmann authored
86 * [Plugins](http://mongoosejs.com/docs/plugins.html)
c659395 @aheckmann docs; fix links
aheckmann authored
87 * [psuedo-JOINs](http://mongoosejs.com/docs/populate.html)
55b825b @rauchg Updated README and example
rauchg authored
88
b4ea66a @rauchg Updated readme and example
rauchg authored
89 The following example shows some of these features:
90
2d50d64 @aheckmann updated readme
aheckmann authored
91 var Comment = new Schema({
92 name : { type: String, default: 'hahaha' }
93 , age : { type: Number, min: 18, index: true }
94 , bio : { type: String, match: /[a-z]/ }
95 , date : { type: Date, default: Date.now }
96 , buff : Buffer
97 });
98
99 // a setter
100 Comment.path('name').set(function (v) {
101 return capitalize(v);
102 });
103
104 // middleware
105 Comment.pre('save', function (next) {
106 notify(this.get('email'));
107 next();
108 });
109
110 Take a look at the example in `examples/schema.js` for an end-to-end example of a typical setup.
55b825b @rauchg Updated README and example
rauchg authored
111
bf7f1df @rauchg Reformated
rauchg authored
112 ## Accessing a Model
55b825b @rauchg Updated README and example
rauchg authored
113
2d50d64 @aheckmann updated readme
aheckmann authored
114 Once we define a model through `mongoose.model('ModelName', mySchema)`, we can access it through the same function
55b825b @rauchg Updated README and example
rauchg authored
115
2d50d64 @aheckmann updated readme
aheckmann authored
116 var myModel = mongoose.model('ModelName');
55b825b @rauchg Updated README and example
rauchg authored
117
c8f4d40 @aheckmann fix indentation
aheckmann authored
118 Or just do it all at once
119
2d50d64 @aheckmann updated readme
aheckmann authored
120 var MyModel = mongoose.model('ModelName', mySchema);
c8f4d40 @aheckmann fix indentation
aheckmann authored
121
121df32 @aheckmann docs
aheckmann authored
122 We can then instantiate it, and save it:
55b825b @rauchg Updated README and example
rauchg authored
123
2d50d64 @aheckmann updated readme
aheckmann authored
124 var instance = new MyModel();
125 instance.my.key = 'hello';
126 instance.save(function (err) {
127 //
128 });
55b825b @rauchg Updated README and example
rauchg authored
129
130 Or we can find documents from the same collection
131
2d50d64 @aheckmann updated readme
aheckmann authored
132 MyModel.find({}, function (err, docs) {
133 // docs.forEach
134 });
55b825b @rauchg Updated README and example
rauchg authored
135
c659395 @aheckmann docs; fix links
aheckmann authored
136 You can also `findOne`, `findById`, `update`, etc. For more details check out [this link](http://mongoosejs.com/docs/queries.html).
55b825b @rauchg Updated README and example
rauchg authored
137
2d50d64 @aheckmann updated readme
aheckmann authored
138 **Important!** If you opened a separate connection using `mongoose.createConnection()` but attempt to access the model through `mongoose.model('ModelName')` it will not work as expected since it is not hooked up to an active db connection. In this case access your model through the connection you created:
121df32 @aheckmann docs
aheckmann authored
139
2d50d64 @aheckmann updated readme
aheckmann authored
140 var conn = mongoose.createConnection('your connection string');
141 var MyModel = conn.model('ModelName', schema);
142 var m = new MyModel;
143 m.save() // works
121df32 @aheckmann docs
aheckmann authored
144
2d50d64 @aheckmann updated readme
aheckmann authored
145 vs
121df32 @aheckmann docs
aheckmann authored
146
2d50d64 @aheckmann updated readme
aheckmann authored
147 var conn = mongoose.createConnection('your connection string');
148 var MyModel = mongoose.model('ModelName', schema);
149 var m = new MyModel;
150 m.save() // does not work b/c the default connection object was never connected
121df32 @aheckmann docs
aheckmann authored
151
bf7f1df @rauchg Reformated
rauchg authored
152 ## Embedded Documents
55b825b @rauchg Updated README and example
rauchg authored
153
154 In the first example snippet, we defined a key in the Schema that looks like:
155
2d50d64 @aheckmann updated readme
aheckmann authored
156 comments: [Comments]
55b825b @rauchg Updated README and example
rauchg authored
157
2d50d64 @aheckmann updated readme
aheckmann authored
158 Where `Comments` is a `Schema` we created. This means that creating embedded documents is as simple as:
55b825b @rauchg Updated README and example
rauchg authored
159
2d50d64 @aheckmann updated readme
aheckmann authored
160 // retrieve my model
161 var BlogPost = mongoose.model('BlogPost');
55b825b @rauchg Updated README and example
rauchg authored
162
2d50d64 @aheckmann updated readme
aheckmann authored
163 // create a blog post
164 var post = new BlogPost();
55b825b @rauchg Updated README and example
rauchg authored
165
2d50d64 @aheckmann updated readme
aheckmann authored
166 // create a comment
167 post.comments.push({ title: 'My comment' });
55b825b @rauchg Updated README and example
rauchg authored
168
2d50d64 @aheckmann updated readme
aheckmann authored
169 post.save(function (err) {
170 if (!err) console.log('Success!');
171 });
55b825b @rauchg Updated README and example
rauchg authored
172
173 The same goes for removing them:
174
2d50d64 @aheckmann updated readme
aheckmann authored
175 BlogPost.findById(myId, function (err, post) {
176 if (!err) {
177 post.comments[0].remove();
178 post.save(function (err) {
179 // do something
180 });
181 }
55b825b @rauchg Updated README and example
rauchg authored
182 });
183
2d50d64 @aheckmann updated readme
aheckmann authored
184 Embedded documents enjoy all the same features as your models. Defaults, validators, middleware. Whenever an error occurs, it's bubbled to the `save()` error callback, so error handling is a snap!
55b825b @rauchg Updated README and example
rauchg authored
185
2d50d64 @aheckmann updated readme
aheckmann authored
186 Mongoose interacts with your embedded documents in arrays _atomically_, out of the box.
55b825b @rauchg Updated README and example
rauchg authored
187
bf7f1df @rauchg Reformated
rauchg authored
188 ## Middleware
55b825b @rauchg Updated README and example
rauchg authored
189
2d50d64 @aheckmann updated readme
aheckmann authored
190 Middleware is one of the most exciting features about Mongoose. Middleware takes away all the pain of nested callbacks.
55b825b @rauchg Updated README and example
rauchg authored
191
2d50d64 @aheckmann updated readme
aheckmann authored
192 Middleware are defined at the Schema level and are applied for the methods `init` (when a document is initialized with data from MongoDB), `save` (when a document or embedded document is saved).
55b825b @rauchg Updated README and example
rauchg authored
193
c21433e @bnoguchi Updated README to reflect changes to the middleware api.
bnoguchi authored
194 There's two types of middleware:
55b825b @rauchg Updated README and example
rauchg authored
195
196 - Serial
197 Serial middleware are defined like:
198
2d50d64 @aheckmann updated readme
aheckmann authored
199 .pre(method, function (next, methodArg1, methodArg2, ...) {
200 // ...
201 })
55b825b @rauchg Updated README and example
rauchg authored
202
203 They're executed one after the other, when each middleware calls `next`.
204
2d50d64 @aheckmann updated readme
aheckmann authored
205 You can also intercept the `method`'s incoming arguments via your middleware -- notice `methodArg1`, `methodArg2`, etc in the `pre` definition above. See section "Intercepting and mutating method arguments" below.
206
c21433e @bnoguchi Updated README to reflect changes to the middleware api.
bnoguchi authored
207
55b825b @rauchg Updated README and example
rauchg authored
208 - Parallel
2d50d64 @aheckmann updated readme
aheckmann authored
209 Parallel middleware offer more fine-grained flow control, and are defined like:
210
211 .pre(method, true, function (next, done, methodArg1, methodArg2) {
212 // ...
213 })
214
215 Parallel middleware can `next()` immediately, but the final argument will be called when all the parallel middleware have called `done()`.
55b825b @rauchg Updated README and example
rauchg authored
216
bf7f1df @rauchg Reformated
rauchg authored
217 ### Error handling
55b825b @rauchg Updated README and example
rauchg authored
218
2d50d64 @aheckmann updated readme
aheckmann authored
219 If any middleware calls `next` or `done` with an `Error` instance, the flow is interrupted, and the error is passed to the function passed as an argument.
55b825b @rauchg Updated README and example
rauchg authored
220
221 For example:
222
2d50d64 @aheckmann updated readme
aheckmann authored
223 schema.pre('save', function (next) {
224 // something goes wrong
225 next(new Error('something went wrong'));
226 });
55b825b @rauchg Updated README and example
rauchg authored
227
2d50d64 @aheckmann updated readme
aheckmann authored
228 // later...
55b825b @rauchg Updated README and example
rauchg authored
229
2d50d64 @aheckmann updated readme
aheckmann authored
230 myModel.save(function (err) {
231 // err can come from a middleware
232 });
55b825b @rauchg Updated README and example
rauchg authored
233
c21433e @bnoguchi Updated README to reflect changes to the middleware api.
bnoguchi authored
234 ### Intercepting and mutating method arguments
235
236 You can intercept method arguments via middleware.
237
2d50d64 @aheckmann updated readme
aheckmann authored
238 For example, this would allow you to broadcast changes about your Documents every time someone `set`s a path in your Document to a new value:
239
240 schema.pre('set', function (next, path, val, typel) {
241 // `this` is the current Document
242 this.emit('set', path, val);
243
244 // Pass control to the next pre
245 next();
246 });
247
248 Moreover, you can mutate the incoming `method` arguments so that subsequent middleware see different values for those arguments. To do so, just pass the new values to `next`:
249
250 .pre(method, function firstPre (next, methodArg1, methodArg2) {
251 // Mutate methodArg1
252 next("altered-" + methodArg1.toString(), methodArg2);
253 })
254
255 // pre declaration is chainable
256 .pre(method, function secondPre (next, methodArg1, methodArg2) {
257 console.log(methodArg1);
258 // => 'altered-originalValOfMethodArg1'
259
260 console.log(methodArg2);
261 // => 'originalValOfMethodArg2'
262
263 // Passing no arguments to `next` automatically passes along the current argument values
264 // i.e., the following `next()` is equivalent to `next(methodArg1, methodArg2)`
265 // and also equivalent to, with the example method arg
266 // values, `next('altered-originalValOfMethodArg1', 'originalValOfMethodArg2')`
267 next();
268 })
c21433e @bnoguchi Updated README to reflect changes to the middleware api.
bnoguchi authored
269
c974aa2 @aheckmann update README with schema 'type' use
aheckmann authored
270 ### Schema gotcha
271
2d50d64 @aheckmann updated readme
aheckmann authored
272 `type`, when used in a schema has special meaning within Mongoose. If your schema requires using `type` as a nested property you must use object notation:
273
274 new Schema({
275 broken: { type: Boolean }
276 , asset : {
277 name: String
278 , type: String // uh oh, it broke. asset will be interpreted as String
279 }
280 });
281
282 new Schema({
283 works: { type: Boolean }
284 , asset : {
285 name: String
286 , type: { type: String } // works. asset is an object with a type property
287 }
288 });
c974aa2 @aheckmann update README with schema 'type' use
aheckmann authored
289
55b825b @rauchg Updated README and example
rauchg authored
290 ## API docs
291
2d50d64 @aheckmann updated readme
aheckmann authored
292 You can find the [Dox](http://github.com/visionmedia/dox) generated API docs [here](http://mongoosejs.com/docs/api.html).
55b825b @rauchg Updated README and example
rauchg authored
293
734b321 @rauchg Added section on support/help
rauchg authored
294 ## Getting support
295
42ed1e1 @aheckmann docs
aheckmann authored
296 - Google Groups [mailing list](http://groups.google.com/group/mongoose-orm)
297 - (irc) #mongoosejs on freenode
298 - reporting [issues](https://github.com/learnboost/mongoose/issues/)
299 - [10gen](http://www.mongodb.org/display/DOCS/Technical+Support)
36fa0c7 @aheckmann add #mongoosejs to README
aheckmann authored
300
943cc86 @aheckmann add note about native driver to README
aheckmann authored
301 ## Driver access
302
c659395 @aheckmann docs; fix links
aheckmann authored
303 The driver being used defaults to [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) and is directly accessible through `YourModel.collection`. **Note**: using the driver directly bypasses all Mongoose power-tools like validation, getters, setters, hooks, etc.
943cc86 @aheckmann add note about native driver to README
aheckmann authored
304
c803092 @bnoguchi Updated README with a list of available plugins.
bnoguchi authored
305 ## Mongoose Plugins
306
eaa29ee @aheckmann Update README.md
aheckmann authored
307 Take a peek at the [plugins search site](http://plugins.mongoosejs.com/) to see related modules from the community.
c803092 @bnoguchi Updated README with a list of available plugins.
bnoguchi authored
308
55b825b @rauchg Updated README and example
rauchg authored
309 ## Contributing to Mongoose
310
311 ### Cloning the repository
312
c659395 @aheckmann docs; fix links
aheckmann authored
313 git clone git://github.com/LearnBoost/mongoose.git
55b825b @rauchg Updated README and example
rauchg authored
314
315 ### Guidelines
316
c659395 @aheckmann docs; fix links
aheckmann authored
317 See [contributing](http://mongoosejs.com/docs/contributing.html).
55b825b @rauchg Updated README and example
rauchg authored
318
eca6f8f @rauchg Added credits and license
rauchg authored
319 ## Credits
320
c659395 @aheckmann docs; fix links
aheckmann authored
321 [contributors](https://github.com/learnboost/mongoose/graphs/contributors)
eca6f8f @rauchg Added credits and license
rauchg authored
322
323 ## License
324
2d50d64 @aheckmann updated readme
aheckmann authored
325 Copyright (c) 2010-2012 LearnBoost <dev@learnboost.com>
eca6f8f @rauchg Added credits and license
rauchg authored
326
327 Permission is hereby granted, free of charge, to any person obtaining
328 a copy of this software and associated documentation files (the
329 'Software'), to deal in the Software without restriction, including
330 without limitation the rights to use, copy, modify, merge, publish,
331 distribute, sublicense, and/or sell copies of the Software, and to
332 permit persons to whom the Software is furnished to do so, subject to
333 the following conditions:
334
335 The above copyright notice and this permission notice shall be
336 included in all copies or substantial portions of the Software.
337
338 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
339 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
340 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
341 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
342 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
343 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
344 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Something went wrong with that request. Please try again.