Inital Commit
[oweals/finalsclub.git] / node_modules / mongoose / README.md
1 Mongoose 1.0
2 ============
3
4 ## What's Mongoose?
5
6 Mongoose is a MongoDB object modeling tool designed to work in an asynchronous
7 environment.
8
9 Defining a model is as easy as:
10
11 ```javascript
12 var Comments = new Schema({
13         title     : String
14   , body      : String
15   , date      : Date
16 });
17
18 var BlogPost = new Schema({
19         author    : ObjectId
20   , title     : String
21   , body      : String
22   , date      : Date
23   , comments  : [Comments]
24   , meta      : {
25                 votes : Number
26           , favs  : Number
27         }
28 });
29
30 mongoose.model('BlogPost', BlogPost);
31 ```
32
33 ## Installation
34
35 The recommended way is through the excellent NPM:
36
37 ```bash
38 $ npm install mongoose
39 ```
40
41 Otherwise, you can check it in your repository and then expose it:
42
43 ```bash
44 $ git clone git@github.com:LearnBoost/mongoose.git support/mongoose/
45 ```
46 ```javascript
47 // in your code
48 require.paths.unshift('support/mongoose/lib')
49 ```
50
51 Then you can `require` it:
52
53 ```javascript
54 require('mongoose')
55 ```
56
57 ## Connecting to MongoDB
58
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`.
62
63 Both `connect` and `createConnection` take a `mongodb://` URI, or the parameters
64 `host, database, port`.
65
66 ```javascript
67 var mongoose = require('mongoose');
68
69 mongoose.connect('mongodb://localhost/my_database');
70 ```
71
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`.
75
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.
79
80 ## Defining a Model
81
82 Models are defined through the `Schema` interface. 
83
84 ```javascript
85 var Schema = mongoose.Schema
86   , ObjectId = Schema.ObjectId;
87
88 var BlogPost = new Schema({
89         author    : ObjectId
90   , title     : String
91   , body      : String
92   , date      : Date
93 });
94 ```
95
96 Aside from defining the structure of your documents and the types of data you're
97 storing, a Schema handles the definition of:
98
99 * Validators (async and sync)
100 * Defaults
101 * Getters
102 * Setters
103 * Indexes
104 * Middleware
105 * Methods definition
106 * Statics definition
107 * Plugins
108
109 The following example shows some of these features:
110
111 ```javascript
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 }
117 });
118
119 // a setter
120 Comment.path('name').set(function (v) {
121   return v.capitalize();
122 });
123
124 // middleware
125 Comment.pre('save', function (next) {
126         notify(this.get('email'));
127         next();
128 });
129 ```
130
131 Take a look at the example in `examples/schema.js` for an end-to-end example of
132 (almost) all the functionality available.
133
134 ## Accessing a Model
135
136 Once we define a model through `mongoose.model('ModelName', mySchema)`, we can
137 access it through the same function
138
139 ```javascript
140 var myModel = mongoose.model('ModelName');
141 ```
142
143 We can then instantiate it, and save it:
144
145 ```javascript
146 var instance = new myModel();
147 instance.my.key = 'hello';
148 instance.save(function (err) {
149   //
150 });
151 ```
152
153 Or we can find documents from the same collection
154
155 ```javascript
156 myModel.find({}, function (err, docs) {
157   // docs.forEach
158 });
159 ```
160
161 You can also `findOne`, `findById`, `update`, etc. For more details check out
162 the API docs.
163
164 ## Embedded Documents
165
166 In the first example snippet, we defined a key in the Schema that looks like:
167
168 ```
169 comments: [Comments]
170 ```
171
172 Where `Comments` is a `Schema` we created. This means that creating embedded
173 documents is as simple as:
174
175 ```javascript
176 // retrieve my model
177 var BlogPost = mongoose.model('BlogPost');
178
179 // create a blog post
180 var post = new BlogPost();
181
182 // create a comment
183 post.comments.push({ title: 'My comment' });
184
185 post.save(function (err) {
186   if (!err) console.log('Success!');
187 });
188 ```
189
190 The same goes for removing them:
191
192 ```javascript
193 BlogPost.findById(myId, function (err, post) {
194   if (!err) {
195     post.comments[0].remove();
196     post.save(function (err) {
197       // do something
198     });
199   }
200 });
201 ```
202
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!
206
207 Mongoose interacts with your embedded documents in arrays _atomically_, out of
208 the box.
209
210 ## Middleware
211
212 Middleware is one of the most exciting features about Mongoose 1.0. Middleware
213 takes away all the pain of nested callbacks.
214
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).
218
219 There's two types of middleware:
220
221 - Serial
222   Serial middleware are defined like:
223
224 ```javascript
225 .pre(method, function (next, methodArg1, methodArg2, ...) {
226   // ...
227 })
228 ```
229
230   They're executed one after the other, when each middleware calls `next`.
231
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.
235   
236
237 - Parallel
238   Parallel middleware offer more fine-grained flow control, and are defined
239   like:
240   
241 ```javascript
242 .pre(method, true, function (next, done, methodArg1, methodArg2) {
243   // ...
244 })
245 ```
246
247   Parallel middleware can `next()` immediately, but the final argument will be
248   called when all the parallel middleware have called `done()`.
249
250 ### Error handling
251
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.
254
255 For example:
256
257 ```javascript
258 schema.pre('save', function (next) {
259   // something goes wrong
260   next(new Error('something went wrong'));
261 });
262
263 // later...
264
265 myModel.save(function (err) {
266   // err can come from a middleware
267 });
268 ```
269
270 ### Intercepting and mutating method arguments
271
272 You can intercept method arguments via middleware.
273
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:
276
277 ```javascript
278 schema.pre('set', function (next, path, val, typel) {
279   // `this` is the current Document
280   this.emit('set', path, val);
281       
282   // Pass control to the next pre
283   next();
284 });
285 ```
286
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`:
290
291 ```javascript
292 .pre(method, function firstPre (next, methodArg1, methodArg2) {
293   // Mutate methodArg1
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' 
299   
300   console.log(methodArg2);
301   // => 'originalValOfMethodArg2' 
302   
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')`
307   next();
308 })
309 ```
310
311 ## API docs
312
313 You can find the [Dox](http://github.com/visionmedia/dox) generated API docs at
314 [http://mongoosejs.com](http://mongoosejs.com).
315
316 ## Getting support
317
318 Please subscribe to the Google Groups [mailing
319 list](http://groups.google.com/group/mongoose-orm/boxsubscribe).
320
321 ## Mongoose Plugins
322
323 The following plugins are currently available for use with mongoose:
324
325 - [mongoose-types](https://github.com/bnoguchi/mongoose-types) - Adds
326   several additional types (e.g., Email) that you can use in your
327   Schema declarations
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
333
334 ## Contributing to Mongoose
335
336 ### Cloning the repository
337
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
340 major release.
341
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).
344
345 ### Guidelines
346
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.
353
354 ## Credits
355
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)
360
361 ## License
362
363 Copyright (c) 2010 LearnBoost <dev@learnboost.com>
364
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:
372
373 The above copyright notice and this permission notice shall be
374 included in all copies or substantial portions of the Software.
375
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.