thoughts/node_modules/mongoose/README.md
node_modules/mongoose/README.mdRaw
1## What's Mongoose?
2
3Mongoose is a [MongoDB](http://www.mongodb.org/) object modeling tool designed to work in an asynchronous environment.
4
5## Documentation
6
7[mongoosejs.com](http://mongoosejs.com/)
8
9## Try it live
10<a href="https://runnable.com/#learnboost/mongoose/code.js/launch" target="_blank"><img src="https://runnable.com/external/styles/assets/runnablebtn.png" style="width:67px;height:25px;"></a>
11
12## Support
13
14 - [Stack Overflow](http://stackoverflow.com/questions/tagged/mongoose)
15 - [bug reports](https://github.com/learnboost/mongoose/issues/)
16 - [help forum](http://groups.google.com/group/mongoose-orm)
17 - [MongoDB support](http://www.mongodb.org/display/DOCS/Technical+Support)
18 - (irc) #mongoosejs on freenode
19
20## Installation
21
22First install [node.js](http://nodejs.org/) and [mongodb](http://www.mongodb.org/downloads).
23
24 $ npm install mongoose
25
26## Plugins
27
28Check out the [plugins search site](http://plugins.mongoosejs.com/) to see hundreds of related modules from the community.
29
30## Contributors
31
32View all 90+ [contributors](https://github.com/learnboost/mongoose/graphs/contributors).
33
34## Get Involved
35
36Stand up and be counted as a [contributor](https://github.com/LearnBoost/mongoose/blob/master/CONTRIBUTING.md) too!
37
38## Overview
39
40### Connecting to MongoDB
41
42First, 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`.
43
44Both `connect` and `createConnection` take a `mongodb://` URI, or the parameters `host, database, port, options`.
45
46 var mongoose = require('mongoose');
47
48 mongoose.connect('mongodb://localhost/my_database');
49
50Once 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`.
51
52**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.
53
54### Defining a Model
55
56Models are defined through the `Schema` interface.
57
58 var Schema = mongoose.Schema
59 , ObjectId = Schema.ObjectId;
60
61 var BlogPost = new Schema({
62 author : ObjectId
63 , title : String
64 , body : String
65 , date : Date
66 });
67
68Aside from defining the structure of your documents and the types of data you're storing, a Schema handles the definition of:
69
70* [Validators](http://mongoosejs.com/docs/validation.html) (async and sync)
71* [Defaults](http://mongoosejs.com/docs/api.html#schematype_SchemaType-default)
72* [Getters](http://mongoosejs.com/docs/api.html#schematype_SchemaType-get)
73* [Setters](http://mongoosejs.com/docs/api.html#schematype_SchemaType-set)
74* [Indexes](http://mongoosejs.com/docs/guide.html#indexes)
75* [Middleware](http://mongoosejs.com/docs/middleware.html)
76* [Methods](http://mongoosejs.com/docs/guide.html#methods) definition
77* [Statics](http://mongoosejs.com/docs/guide.html#statics) definition
78* [Plugins](http://mongoosejs.com/docs/plugins.html)
79* [pseudo-JOINs](http://mongoosejs.com/docs/populate.html)
80
81The following example shows some of these features:
82
83 var Comment = new Schema({
84 name : { type: String, default: 'hahaha' }
85 , age : { type: Number, min: 18, index: true }
86 , bio : { type: String, match: /[a-z]/ }
87 , date : { type: Date, default: Date.now }
88 , buff : Buffer
89 });
90
91 // a setter
92 Comment.path('name').set(function (v) {
93 return capitalize(v);
94 });
95
96 // middleware
97 Comment.pre('save', function (next) {
98 notify(this.get('email'));
99 next();
100 });
101
102Take a look at the example in `examples/schema.js` for an end-to-end example of a typical setup.
103
104### Accessing a Model
105
106Once we define a model through `mongoose.model('ModelName', mySchema)`, we can access it through the same function
107
108 var myModel = mongoose.model('ModelName');
109
110Or just do it all at once
111
112 var MyModel = mongoose.model('ModelName', mySchema);
113
114We can then instantiate it, and save it:
115
116 var instance = new MyModel();
117 instance.my.key = 'hello';
118 instance.save(function (err) {
119 //
120 });
121
122Or we can find documents from the same collection
123
124 MyModel.find({}, function (err, docs) {
125 // docs.forEach
126 });
127
128You can also `findOne`, `findById`, `update`, etc. For more details check out [the docs](http://mongoosejs.com/docs/queries.html).
129
130**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:
131
132 var conn = mongoose.createConnection('your connection string');
133 var MyModel = conn.model('ModelName', schema);
134 var m = new MyModel;
135 m.save() // works
136
137 vs
138
139 var conn = mongoose.createConnection('your connection string');
140 var MyModel = mongoose.model('ModelName', schema);
141 var m = new MyModel;
142 m.save() // does not work b/c the default connection object was never connected
143
144### Embedded Documents
145
146In the first example snippet, we defined a key in the Schema that looks like:
147
148 comments: [Comments]
149
150Where `Comments` is a `Schema` we created. This means that creating embedded documents is as simple as:
151
152 // retrieve my model
153 var BlogPost = mongoose.model('BlogPost');
154
155 // create a blog post
156 var post = new BlogPost();
157
158 // create a comment
159 post.comments.push({ title: 'My comment' });
160
161 post.save(function (err) {
162 if (!err) console.log('Success!');
163 });
164
165The same goes for removing them:
166
167 BlogPost.findById(myId, function (err, post) {
168 if (!err) {
169 post.comments[0].remove();
170 post.save(function (err) {
171 // do something
172 });
173 }
174 });
175
176Embedded 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!
177
178Mongoose interacts with your embedded documents in arrays _atomically_, out of the box.
179
180### Middleware
181
182See the [docs](http://mongoosejs.com/docs/middleware.html) page.
183
184#### Intercepting and mutating method arguments
185
186You can intercept method arguments via middleware.
187
188For 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:
189
190 schema.pre('set', function (next, path, val, typel) {
191 // `this` is the current Document
192 this.emit('set', path, val);
193
194 // Pass control to the next pre
195 next();
196 });
197
198Moreover, 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`:
199
200 .pre(method, function firstPre (next, methodArg1, methodArg2) {
201 // Mutate methodArg1
202 next("altered-" + methodArg1.toString(), methodArg2);
203 })
204
205 // pre declaration is chainable
206 .pre(method, function secondPre (next, methodArg1, methodArg2) {
207 console.log(methodArg1);
208 // => 'altered-originalValOfMethodArg1'
209
210 console.log(methodArg2);
211 // => 'originalValOfMethodArg2'
212
213 // Passing no arguments to `next` automatically passes along the current argument values
214 // i.e., the following `next()` is equivalent to `next(methodArg1, methodArg2)`
215 // and also equivalent to, with the example method arg
216 // values, `next('altered-originalValOfMethodArg1', 'originalValOfMethodArg2')`
217 next();
218 })
219
220#### Schema gotcha
221
222`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:
223
224 new Schema({
225 broken: { type: Boolean }
226 , asset : {
227 name: String
228 , type: String // uh oh, it broke. asset will be interpreted as String
229 }
230 });
231
232 new Schema({
233 works: { type: Boolean }
234 , asset : {
235 name: String
236 , type: { type: String } // works. asset is an object with a type property
237 }
238 });
239
240### Driver access
241
242The 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.
243
244## API Docs
245
246Find the API docs [here](http://mongoosejs.com/docs/api.html), generated by [dox](http://github.com/visionmedia/dox).
247
248## License
249
250Copyright (c) 2010 LearnBoost <dev@learnboost.com>
251
252Permission is hereby granted, free of charge, to any person obtaining
253a copy of this software and associated documentation files (the
254'Software'), to deal in the Software without restriction, including
255without limitation the rights to use, copy, modify, merge, publish,
256distribute, sublicense, and/or sell copies of the Software, and to
257permit persons to whom the Software is furnished to do so, subject to
258the following conditions:
259
260The above copyright notice and this permission notice shall be
261included in all copies or substantial portions of the Software.
262
263THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
264EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
265MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
266IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
267CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
268TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
269SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.