Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 345 lines (234 sloc) 12.277 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
f7b0648 @rauchg Added installation section
rauchg authored
28 ## Installation
29
2c293e0 @aheckmann release 2.0.0
aheckmann authored
30 The recommended way is through the excellent [NPM](http://www.npmjs.org/):
f7b0648 @rauchg Added installation section
rauchg authored
31
2d50d64 @aheckmann updated readme
aheckmann authored
32 $ npm install mongoose
f7b0648 @rauchg Added installation section
rauchg authored
33
34 Otherwise, you can check it in your repository and then expose it:
35
2d50d64 @aheckmann updated readme
aheckmann authored
36 $ git clone git://github.com/LearnBoost/mongoose.git node_modules/mongoose/
37
a544842 @tricknotes fixed README
tricknotes authored
38 And install dependency modules written on `package.json`.
f7b0648 @rauchg Added installation section
rauchg authored
39
69ce567 Added syntax highlighting.
Tony authored
40 Then you can `require` it:
f7b0648 @rauchg Added installation section
rauchg authored
41
2d50d64 @aheckmann updated readme
aheckmann authored
42 require('mongoose')
f7b0648 @rauchg Added installation section
rauchg authored
43
bf7f1df @rauchg Reformated
rauchg authored
44 ## Connecting to MongoDB
55b825b @rauchg Updated README and example
rauchg authored
45
2d50d64 @aheckmann updated readme
aheckmann authored
46 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
47
2d50d64 @aheckmann updated readme
aheckmann authored
48 Both `connect` and `createConnection` take a `mongodb://` URI, or the parameters `host, database, port, options`.
55b825b @rauchg Updated README and example
rauchg authored
49
2d50d64 @aheckmann updated readme
aheckmann authored
50 var mongoose = require('mongoose');
55b825b @rauchg Updated README and example
rauchg authored
51
2d50d64 @aheckmann updated readme
aheckmann authored
52 mongoose.connect('mongodb://localhost/my_database');
55b825b @rauchg Updated README and example
rauchg authored
53
2d50d64 @aheckmann updated readme
aheckmann authored
54 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
55
2d50d64 @aheckmann updated readme
aheckmann authored
56 **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
57
bf7f1df @rauchg Reformated
rauchg authored
58 ## Defining a Model
55b825b @rauchg Updated README and example
rauchg authored
59
60 Models are defined through the `Schema` interface.
61
2d50d64 @aheckmann updated readme
aheckmann authored
62 var Schema = mongoose.Schema
63 , ObjectId = Schema.ObjectId;
55b825b @rauchg Updated README and example
rauchg authored
64
2d50d64 @aheckmann updated readme
aheckmann authored
65 var BlogPost = new Schema({
66 author : ObjectId
67 , title : String
68 , body : String
69 , date : Date
70 });
55b825b @rauchg Updated README and example
rauchg authored
71
2d50d64 @aheckmann updated readme
aheckmann authored
72 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
73
2c293e0 @aheckmann release 2.0.0
aheckmann authored
74 * [Validators](http://mongoosejs.com/docs/validation.html) (async and sync)
75 * [Defaults](http://mongoosejs.com/docs/schematypes.html)
76 * [Getters](http://mongoosejs.com/docs/getters-setters.html)
77 * [Setters](http://mongoosejs.com/docs/getters-setters.html)
78 * [Indexes](http://mongoosejs.com/docs/indexes.html)
79 * [Middleware](http://mongoosejs.com/docs/middleware.html)
80 * [Methods](http://mongoosejs.com/docs/methods-statics.html) definition
81 * [Statics](http://mongoosejs.com/docs/methods-statics.html) definition
82 * [Plugins](http://mongoosejs.com/docs/plugins.html)
83 * [DBRefs](http://mongoosejs.com/docs/dbrefs.html)
55b825b @rauchg Updated README and example
rauchg authored
84
b4ea66a @rauchg Updated readme and example
rauchg authored
85 The following example shows some of these features:
86
2d50d64 @aheckmann updated readme
aheckmann authored
87 var Comment = new Schema({
88 name : { type: String, default: 'hahaha' }
89 , age : { type: Number, min: 18, index: true }
90 , bio : { type: String, match: /[a-z]/ }
91 , date : { type: Date, default: Date.now }
92 , buff : Buffer
93 });
94
95 // a setter
96 Comment.path('name').set(function (v) {
97 return capitalize(v);
98 });
99
100 // middleware
101 Comment.pre('save', function (next) {
102 notify(this.get('email'));
103 next();
104 });
105
106 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
107
bf7f1df @rauchg Reformated
rauchg authored
108 ## Accessing a Model
55b825b @rauchg Updated README and example
rauchg authored
109
2d50d64 @aheckmann updated readme
aheckmann authored
110 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
111
2d50d64 @aheckmann updated readme
aheckmann authored
112 var myModel = mongoose.model('ModelName');
55b825b @rauchg Updated README and example
rauchg authored
113
c8f4d40 @aheckmann fix indentation
aheckmann authored
114 Or just do it all at once
115
2d50d64 @aheckmann updated readme
aheckmann authored
116 var MyModel = mongoose.model('ModelName', mySchema);
c8f4d40 @aheckmann fix indentation
aheckmann authored
117
121df32 @aheckmann docs
aheckmann authored
118 We can then instantiate it, and save it:
55b825b @rauchg Updated README and example
rauchg authored
119
2d50d64 @aheckmann updated readme
aheckmann authored
120 var instance = new MyModel();
121 instance.my.key = 'hello';
122 instance.save(function (err) {
123 //
124 });
55b825b @rauchg Updated README and example
rauchg authored
125
126 Or we can find documents from the same collection
127
2d50d64 @aheckmann updated readme
aheckmann authored
128 MyModel.find({}, function (err, docs) {
129 // docs.forEach
130 });
55b825b @rauchg Updated README and example
rauchg authored
131
2d50d64 @aheckmann updated readme
aheckmann authored
132 You can also `findOne`, `findById`, `update`, etc. For more details check out [this link](http://mongoosejs.com/docs/finding-documents.html).
55b825b @rauchg Updated README and example
rauchg authored
133
2d50d64 @aheckmann updated readme
aheckmann authored
134 **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
135
2d50d64 @aheckmann updated readme
aheckmann authored
136 var conn = mongoose.createConnection('your connection string');
137 var MyModel = conn.model('ModelName', schema);
138 var m = new MyModel;
139 m.save() // works
121df32 @aheckmann docs
aheckmann authored
140
2d50d64 @aheckmann updated readme
aheckmann authored
141 vs
121df32 @aheckmann docs
aheckmann authored
142
2d50d64 @aheckmann updated readme
aheckmann authored
143 var conn = mongoose.createConnection('your connection string');
144 var MyModel = mongoose.model('ModelName', schema);
145 var m = new MyModel;
146 m.save() // does not work b/c the default connection object was never connected
121df32 @aheckmann docs
aheckmann authored
147
bf7f1df @rauchg Reformated
rauchg authored
148 ## Embedded Documents
55b825b @rauchg Updated README and example
rauchg authored
149
150 In the first example snippet, we defined a key in the Schema that looks like:
151
2d50d64 @aheckmann updated readme
aheckmann authored
152 comments: [Comments]
55b825b @rauchg Updated README and example
rauchg authored
153
2d50d64 @aheckmann updated readme
aheckmann authored
154 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
155
2d50d64 @aheckmann updated readme
aheckmann authored
156 // retrieve my model
157 var BlogPost = mongoose.model('BlogPost');
55b825b @rauchg Updated README and example
rauchg authored
158
2d50d64 @aheckmann updated readme
aheckmann authored
159 // create a blog post
160 var post = new BlogPost();
55b825b @rauchg Updated README and example
rauchg authored
161
2d50d64 @aheckmann updated readme
aheckmann authored
162 // create a comment
163 post.comments.push({ title: 'My comment' });
55b825b @rauchg Updated README and example
rauchg authored
164
2d50d64 @aheckmann updated readme
aheckmann authored
165 post.save(function (err) {
166 if (!err) console.log('Success!');
167 });
55b825b @rauchg Updated README and example
rauchg authored
168
169 The same goes for removing them:
170
2d50d64 @aheckmann updated readme
aheckmann authored
171 BlogPost.findById(myId, function (err, post) {
172 if (!err) {
173 post.comments[0].remove();
174 post.save(function (err) {
175 // do something
176 });
177 }
55b825b @rauchg Updated README and example
rauchg authored
178 });
179
2d50d64 @aheckmann updated readme
aheckmann authored
180 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
181
2d50d64 @aheckmann updated readme
aheckmann authored
182 Mongoose interacts with your embedded documents in arrays _atomically_, out of the box.
55b825b @rauchg Updated README and example
rauchg authored
183
bf7f1df @rauchg Reformated
rauchg authored
184 ## Middleware
55b825b @rauchg Updated README and example
rauchg authored
185
2d50d64 @aheckmann updated readme
aheckmann authored
186 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
187
2d50d64 @aheckmann updated readme
aheckmann authored
188 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
189
c21433e @bnoguchi Updated README to reflect changes to the middleware api.
bnoguchi authored
190 There's two types of middleware:
55b825b @rauchg Updated README and example
rauchg authored
191
192 - Serial
193 Serial middleware are defined like:
194
2d50d64 @aheckmann updated readme
aheckmann authored
195 .pre(method, function (next, methodArg1, methodArg2, ...) {
196 // ...
197 })
55b825b @rauchg Updated README and example
rauchg authored
198
199 They're executed one after the other, when each middleware calls `next`.
200
2d50d64 @aheckmann updated readme
aheckmann authored
201 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.
202
c21433e @bnoguchi Updated README to reflect changes to the middleware api.
bnoguchi authored
203
55b825b @rauchg Updated README and example
rauchg authored
204 - Parallel
2d50d64 @aheckmann updated readme
aheckmann authored
205 Parallel middleware offer more fine-grained flow control, and are defined like:
206
207 .pre(method, true, function (next, done, methodArg1, methodArg2) {
208 // ...
209 })
210
211 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
212
bf7f1df @rauchg Reformated
rauchg authored
213 ### Error handling
55b825b @rauchg Updated README and example
rauchg authored
214
2d50d64 @aheckmann updated readme
aheckmann authored
215 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
216
217 For example:
218
2d50d64 @aheckmann updated readme
aheckmann authored
219 schema.pre('save', function (next) {
220 // something goes wrong
221 next(new Error('something went wrong'));
222 });
55b825b @rauchg Updated README and example
rauchg authored
223
2d50d64 @aheckmann updated readme
aheckmann authored
224 // later...
55b825b @rauchg Updated README and example
rauchg authored
225
2d50d64 @aheckmann updated readme
aheckmann authored
226 myModel.save(function (err) {
227 // err can come from a middleware
228 });
55b825b @rauchg Updated README and example
rauchg authored
229
c21433e @bnoguchi Updated README to reflect changes to the middleware api.
bnoguchi authored
230 ### Intercepting and mutating method arguments
231
232 You can intercept method arguments via middleware.
233
2d50d64 @aheckmann updated readme
aheckmann authored
234 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:
235
236 schema.pre('set', function (next, path, val, typel) {
237 // `this` is the current Document
238 this.emit('set', path, val);
239
240 // Pass control to the next pre
241 next();
242 });
243
244 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`:
245
246 .pre(method, function firstPre (next, methodArg1, methodArg2) {
247 // Mutate methodArg1
248 next("altered-" + methodArg1.toString(), methodArg2);
249 })
250
251 // pre declaration is chainable
252 .pre(method, function secondPre (next, methodArg1, methodArg2) {
253 console.log(methodArg1);
254 // => 'altered-originalValOfMethodArg1'
255
256 console.log(methodArg2);
257 // => 'originalValOfMethodArg2'
258
259 // Passing no arguments to `next` automatically passes along the current argument values
260 // i.e., the following `next()` is equivalent to `next(methodArg1, methodArg2)`
261 // and also equivalent to, with the example method arg
262 // values, `next('altered-originalValOfMethodArg1', 'originalValOfMethodArg2')`
263 next();
264 })
c21433e @bnoguchi Updated README to reflect changes to the middleware api.
bnoguchi authored
265
c974aa2 @aheckmann update README with schema 'type' use
aheckmann authored
266 ### Schema gotcha
267
2d50d64 @aheckmann updated readme
aheckmann authored
268 `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:
269
270 new Schema({
271 broken: { type: Boolean }
272 , asset : {
273 name: String
274 , type: String // uh oh, it broke. asset will be interpreted as String
275 }
276 });
277
278 new Schema({
279 works: { type: Boolean }
280 , asset : {
281 name: String
282 , type: { type: String } // works. asset is an object with a type property
283 }
284 });
c974aa2 @aheckmann update README with schema 'type' use
aheckmann authored
285
55b825b @rauchg Updated README and example
rauchg authored
286 ## API docs
287
2d50d64 @aheckmann updated readme
aheckmann authored
288 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
289
734b321 @rauchg Added section on support/help
rauchg authored
290 ## Getting support
291
2d50d64 @aheckmann updated readme
aheckmann authored
292 Please subscribe to the Google Groups [mailing list](http://groups.google.com/group/mongoose-orm).
734b321 @rauchg Added section on support/help
rauchg authored
293
36fa0c7 @aheckmann add #mongoosejs to README
aheckmann authored
294 Join #mongoosejs on freenode.
295
943cc86 @aheckmann add note about native driver to README
aheckmann authored
296 ## Driver access
297
298 The driver being used defaults to [node-mongodb-native](https://github.com/christkv/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.
299
c803092 @bnoguchi Updated README with a list of available plugins.
bnoguchi authored
300 ## Mongoose Plugins
301
ffa5a8f @aheckmann refer the the plugins page
aheckmann authored
302 Take a peek at the [plugins page](https://github.com/LearnBoost/mongoose/wiki/Plugins) to see contributions from the community. Add your own!
c803092 @bnoguchi Updated README with a list of available plugins.
bnoguchi authored
303
55b825b @rauchg Updated README and example
rauchg authored
304 ## Contributing to Mongoose
305
306 ### Cloning the repository
307
2d50d64 @aheckmann updated readme
aheckmann authored
308 Make a fork of `mongoose`, then clone it in your computer. The `v2.x` branch contains the current stable release, and the `master` branch the next upcoming major release.
55b825b @rauchg Updated README and example
rauchg authored
309
310 ### Guidelines
311
312 - Please write inline documentation for new methods or class members.
313 - Please write tests and make sure your tests pass.
2d50d64 @aheckmann updated readme
aheckmann authored
314 - Before starting to write code, look for existing tickets or create one for your specific issue (unless you're addressing something that's clearly broken). That way you avoid working on something that might not be of interest or that has been addressed already in a different branch.
55b825b @rauchg Updated README and example
rauchg authored
315
eca6f8f @rauchg Added credits and license
rauchg authored
316 ## Credits
317
07c41f5 @rauchg Updated readme
rauchg authored
318 - Guillermo Rauch - guillermo@learnboost.com - [Guille](http://github.com/guille)
319 - Nathan White - [nw](http://github.com/nw/)
320 - Brian Noguchi - [bnoguchi](https://github.com/bnoguchi)
ea5a715 @aheckmann add aheckmann to credits
aheckmann authored
321 - Aaron Heckmann - [aheckmann](https://github.com/aheckmann)
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.