UNPKG

12.2 kBMarkdownView Raw
1# Mongoose
2
3Mongoose is a [MongoDB](https://www.mongodb.org/) object modeling tool designed to work in an asynchronous environment.
4
5[![Slack Status](http://slack.mongoosejs.io/badge.svg)](http://slack.mongoosejs.io)
6[![Build Status](https://api.travis-ci.org/Automattic/mongoose.svg?branch=master)](https://travis-ci.org/Automattic/mongoose)
7[![NPM version](https://badge.fury.io/js/mongoose.svg)](http://badge.fury.io/js/mongoose)
8
9[![npm](https://nodei.co/npm/mongoose.png)](https://www.npmjs.com/package/mongoose)
10
11## Documentation
12
13[mongoosejs.com](http://mongoosejs.com/)
14
15[Mongoose 5.0.0](https://github.com/Automattic/mongoose/blob/master/History.md#500--2018-01-17) was released on January 17, 2018. You can find more details on [backwards breaking changes in 5.0.0 on our docs site](https://mongoosejs.com/docs/migrating_to_5.html).
16
17## Support
18
19 - [Stack Overflow](http://stackoverflow.com/questions/tagged/mongoose)
20 - [Bug Reports](https://github.com/Automattic/mongoose/issues/)
21 - [Mongoose Slack Channel](http://slack.mongoosejs.io/)
22 - [Help Forum](http://groups.google.com/group/mongoose-orm)
23 - [MongoDB Support](https://docs.mongodb.org/manual/support/)
24
25## Importing
26
27```javascript
28// Using Node.js `require()`
29const mongoose = require('mongoose');
30
31// Using ES6 imports
32import mongoose from 'mongoose';
33```
34
35## Plugins
36
37Check out the [plugins search site](http://plugins.mongoosejs.io/) to see hundreds of related modules from the community. Next, learn how to write your own plugin from the [docs](http://mongoosejs.com/docs/plugins.html) or [this blog post](http://thecodebarbarian.com/2015/03/06/guide-to-mongoose-plugins).
38
39## Contributors
40
41Pull requests are always welcome! Please base pull requests against the `master`
42branch and follow the [contributing guide](https://github.com/Automattic/mongoose/blob/master/CONTRIBUTING.md).
43
44If your pull requests makes documentation changes, please do **not**
45modify any `.html` files. The `.html` files are compiled code, so please make
46your changes in `docs/*.pug`, `lib/*.js`, or `test/docs/*.js`.
47
48View all 400+ [contributors](https://github.com/Automattic/mongoose/graphs/contributors).
49
50## Installation
51
52First install [node.js](http://nodejs.org/) and [mongodb](https://www.mongodb.org/downloads). Then:
53
54```sh
55$ npm install mongoose
56```
57
58## Overview
59
60### Connecting to MongoDB
61
62First, we need to define a connection. If your app uses only one database, you should use `mongoose.connect`. If you need to create additional connections, use `mongoose.createConnection`.
63
64Both `connect` and `createConnection` take a `mongodb://` URI, or the parameters `host, database, port, options`.
65
66```js
67const mongoose = require('mongoose');
68
69mongoose.connect('mongodb://localhost/my_database', {useNewUrlParser: true});
70```
71
72Once 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`.
73
74**Note:** _If the local connection fails then try using 127.0.0.1 instead of localhost. Sometimes issues may arise when the local hostname has been changed._
75
76**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.
77
78### Defining a Model
79
80Models are defined through the `Schema` interface.
81
82```js
83const Schema = mongoose.Schema;
84const ObjectId = Schema.ObjectId;
85
86const BlogPost = new Schema({
87 author: ObjectId,
88 title: String,
89 body: String,
90  date: Date
91});
92```
93
94Aside from defining the structure of your documents and the types of data you're storing, a Schema handles the definition of:
95
96* [Validators](http://mongoosejs.com/docs/validation.html) (async and sync)
97* [Defaults](http://mongoosejs.com/docs/api.html#schematype_SchemaType-default)
98* [Getters](http://mongoosejs.com/docs/api.html#schematype_SchemaType-get)
99* [Setters](http://mongoosejs.com/docs/api.html#schematype_SchemaType-set)
100* [Indexes](http://mongoosejs.com/docs/guide.html#indexes)
101* [Middleware](http://mongoosejs.com/docs/middleware.html)
102* [Methods](http://mongoosejs.com/docs/guide.html#methods) definition
103* [Statics](http://mongoosejs.com/docs/guide.html#statics) definition
104* [Plugins](http://mongoosejs.com/docs/plugins.html)
105* [pseudo-JOINs](http://mongoosejs.com/docs/populate.html)
106
107The following example shows some of these features:
108
109```js
110const Comment = new Schema({
111 name: { type: String, default: 'hahaha' },
112 age: { type: Number, min: 18, index: true },
113 bio: { type: String, match: /[a-z]/ },
114 date: { type: Date, default: Date.now },
115 buff: Buffer
116});
117
118// a setter
119Comment.path('name').set(function (v) {
120 return capitalize(v);
121});
122
123// middleware
124Comment.pre('save', function (next) {
125 notify(this.get('email'));
126 next();
127});
128```
129
130Take a look at the example in [`examples/schema/schema.js`](https://github.com/Automattic/mongoose/blob/master/examples/schema/schema.js) for an end-to-end example of a typical setup.
131
132### Accessing a Model
133
134Once we define a model through `mongoose.model('ModelName', mySchema)`, we can access it through the same function
135
136```js
137const MyModel = mongoose.model('ModelName');
138```
139
140Or just do it all at once
141
142```js
143const MyModel = mongoose.model('ModelName', mySchema);
144```
145
146The first argument is the _singular_ name of the collection your model is for. **Mongoose automatically looks for the _plural_ version of your model name.** For example, if you use
147
148```js
149const MyModel = mongoose.model('Ticket', mySchema);
150```
151
152Then Mongoose will create the model for your __tickets__ collection, not your __ticket__ collection.
153
154Once we have our model, we can then instantiate it, and save it:
155
156```js
157const instance = new MyModel();
158instance.my.key = 'hello';
159instance.save(function (err) {
160 //
161});
162```
163
164Or we can find documents from the same collection
165
166```js
167MyModel.find({}, function (err, docs) {
168 // docs.forEach
169});
170```
171
172You can also `findOne`, `findById`, `update`, etc. For more details check out [the docs](http://mongoosejs.com/docs/queries.html).
173
174**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:
175
176```js
177const conn = mongoose.createConnection('your connection string');
178const MyModel = conn.model('ModelName', schema);
179const m = new MyModel;
180m.save(); // works
181```
182
183vs
184
185```js
186const conn = mongoose.createConnection('your connection string');
187const MyModel = mongoose.model('ModelName', schema);
188const m = new MyModel;
189m.save(); // does not work b/c the default connection object was never connected
190```
191
192### Embedded Documents
193
194In the first example snippet, we defined a key in the Schema that looks like:
195
196```
197comments: [Comment]
198```
199
200Where `Comment` is a `Schema` we created. This means that creating embedded documents is as simple as:
201
202```js
203// retrieve my model
204const BlogPost = mongoose.model('BlogPost');
205
206// create a blog post
207const post = new BlogPost();
208
209// create a comment
210post.comments.push({ title: 'My comment' });
211
212post.save(function (err) {
213 if (!err) console.log('Success!');
214});
215```
216
217The same goes for removing them:
218
219```js
220BlogPost.findById(myId, function (err, post) {
221 if (!err) {
222 post.comments[0].remove();
223 post.save(function (err) {
224 // do something
225 });
226 }
227});
228```
229
230Embedded 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!
231
232
233### Middleware
234
235See the [docs](http://mongoosejs.com/docs/middleware.html) page.
236
237#### Intercepting and mutating method arguments
238
239You can intercept method arguments via middleware.
240
241For 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:
242
243```js
244schema.pre('set', function (next, path, val, typel) {
245 // `this` is the current Document
246 this.emit('set', path, val);
247
248 // Pass control to the next pre
249 next();
250});
251```
252
253Moreover, 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`:
254
255```js
256.pre(method, function firstPre (next, methodArg1, methodArg2) {
257 // Mutate methodArg1
258 next("altered-" + methodArg1.toString(), methodArg2);
259});
260
261// pre declaration is chainable
262.pre(method, function secondPre (next, methodArg1, methodArg2) {
263 console.log(methodArg1);
264 // => 'altered-originalValOfMethodArg1'
265
266 console.log(methodArg2);
267 // => 'originalValOfMethodArg2'
268
269 // Passing no arguments to `next` automatically passes along the current argument values
270 // i.e., the following `next()` is equivalent to `next(methodArg1, methodArg2)`
271 // and also equivalent to, with the example method arg
272 // values, `next('altered-originalValOfMethodArg1', 'originalValOfMethodArg2')`
273 next();
274});
275```
276
277#### Schema gotcha
278
279`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:
280
281```js
282new Schema({
283 broken: { type: Boolean },
284 asset: {
285 name: String,
286 type: String // uh oh, it broke. asset will be interpreted as String
287 }
288});
289
290new Schema({
291 works: { type: Boolean },
292 asset: {
293 name: String,
294 type: { type: String } // works. asset is an object with a type property
295 }
296});
297```
298
299### Driver Access
300
301Mongoose is built on top of the [official MongoDB Node.js driver](https://github.com/mongodb/node-mongodb-native). Each mongoose model keeps a reference to a [native MongoDB driver collection](http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html). The collection object can be accessed using `YourModel.collection`. However, using the collection object directly bypasses all mongoose features, including hooks, validation, etc. The one
302notable exception that `YourModel.collection` still buffers
303commands. As such, `YourModel.collection.find()` will **not**
304return a cursor.
305
306## API Docs
307
308Find the API docs [here](http://mongoosejs.com/docs/api.html), generated using [dox](https://github.com/tj/dox)
309and [acquit](https://github.com/vkarpov15/acquit).
310
311## Related Projects
312
313#### MongoDB Runners
314
315- [run-rs](https://www.npmjs.com/package/run-rs)
316- [mongodb-memory-server](https://www.npmjs.com/package/mongodb-memory-server)
317- [mongodb-topology-manager](https://www.npmjs.com/package/mongodb-topology-manager)
318
319#### Data Seeding
320
321- [dookie](https://www.npmjs.com/package/dookie)
322- [seedgoose](https://www.npmjs.com/package/seedgoose)
323- [mongoose-data-seed](https://www.npmjs.com/package/mongoose-data-seed)
324
325#### Express Session Stores
326
327- [connect-mongodb-session](https://www.npmjs.com/package/connect-mongodb-session)
328- [connect-mongo](https://www.npmjs.com/package/connect-mongo)
329
330## License
331
332Copyright (c) 2010 LearnBoost <dev@learnboost.com>
333
334Permission is hereby granted, free of charge, to any person obtaining
335a copy of this software and associated documentation files (the
336'Software'), to deal in the Software without restriction, including
337without limitation the rights to use, copy, modify, merge, publish,
338distribute, sublicense, and/or sell copies of the Software, and to
339permit persons to whom the Software is furnished to do so, subject to
340the following conditions:
341
342The above copyright notice and this permission notice shall be
343included in all copies or substantial portions of the Software.
344
345THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
346EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
347MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
348IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
349CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
350TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
351SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.