modella-mongo
v0.2.15
Published
Modella Mongo persistence layer
Downloads
17
Readme
Modella-Mongo
Mongo plugin for modella. Thinly built on top of kissjs/node-mongoskin.
Installation
npm install modella-mongo
Example
var model = require('modella');
mongo = require('modella-mongo')('localhost/db');
var User = model('user')
.attr('_id')
.attr('name')
.attr('email', { unique: true })
.attr('password');
User.use(mongo);
/**
* Initialize
*/
var user = new User;
user.name('matt');
user.save(function(err) {
console.log(user.toJSON());
});
Implemented Sync Layer Methods
By adding the plugin, modella 0.2.0 compliant sync layer methods are added. This
enables instance#save()
and instance#remove()
to work with mongo.
Configuration
By default, modella-mongo
will use Model.modelName
for the Collection. For example:
var mongo = require('modella-mongo')(connectionString);
var User = modella('User');
User.use(mongo); // Uses db.User
If you want, you can also specify a collection name yourself by passing it as a function to mongo
. For example:
var mongo = require('modella-mongo')(connectionString);
var User = modella('User');
User.use(mongo('Account')); // Uses db.Account
Attribute Configuration
{'unique': true}
This will create a unique index for the attribute
False by default
{'atomic': true}
Uses the '$inc'
update modifier for mongo, allowing a value to be (de)incremented as needed, rather than using '$set'
each time.
This only works for number attributes.
False by default
{'type': 'type string or constructor'}
Since [email protected]
the toJSON
method is recursive. This causes
objects that can be stored as one of mongodb's BSON types to be
converted unecessarily into strings. To prevent this behavior, define
types for attributes where appropriate. You do not need to do this for
the _id
attribute.
The currently available types are Dates and ObjectIds
var User = modella('User');
var mongo = require('modella-mongo')(connectionString);
// The ObjectID constructor is made available at mongo.ObjectId
User.attr('_id')
// This attribute will always be stored as an ObjectID in the database
.attr('referredBy', {type: 'ObjectId'})
// you can also use 'ObjectID' or the actual ObjectID constructor
// This attribute will always be stroed as an ISODate object in the database
.attr('joined', {type: 'date'});
// you can also use the Date constructor
Using the constructor rather than a type string is recommended when
using modella-mongo
in conjunction with the
modella-validators
plugin.
API
module.exports.ObjectID
module.exports.ObjectId
An alias of the mongoskin.ObjectID constructor
Model Methods
By loading this plugin, Model
inherits:
Model.db
Object pointing to the raw mongoskin database. Use it to manipulate the collection directly.
Model#index(attr, options)
Index an attribute in mongo.
User.index('email', { unique : true });
Alternatively, you can specify unique: true
when defining an attribute.
User.attr('username', {unique: true});
// Equivilent to...
User.attr('username');
User.index('username', {unique: true, sparse: true});
Model.all(query, [options], fn)
Queries for all users in the collection that match the given query
. Additional
options can be passed in (eg. {sort: {age: -1}}
).
Calls fn(err, instances)
where instances
is an array of Model instances. If
no documents match, instances
will be empty.
User.all({emailConfirmed: true}, {sort: {emailConfirmationDate: 1}}, function(err, users) {
console.log("Users with confirmed emails: ");
users.forEach(function(u) {
console.log(u.username());
});
});
Model.find/get(query, [options], fn)
Queries for one user in the collection that match the given query
. Additional
options can be passed in (eg. {sort: {age: -1}}
).
query
can also be a string, in which case it will be converted to an
ObjectId
.
Calls fn(err, instance)
where instance
is an instance of Model. If
no documents match, instance
will be false
.
User.get == User.find // true
User.find('528263fa996abeabbe000002', function(err, u) {
console.log(u.username());
});
Calls fn(err, instances)
where instances
is an array of Model instances. If
no queries match, instances will be false
.
Model.removeAll(query, [options], fn)
Removes all records that match the given query
.
Calls fn(err, count)
where count
is the number of records removed. If
no queries match, instances will be false
.
User.removeAll({emailConfirmed: false}, function(err, count) {
console.log("%d users were deleted", count);
});
Model.query()
Returns a wrapped instances of mquery
. See mquery support below.
Model.aggregate()
Returns a wrapped instances of maggregate
. See maggregate support below.
mquery support
modella-mongo
provides a wrapped version of the wonderful mquery
query builder. To get it, simply call Model.query()
.
This allows you to build readable and robust queries easily. When approprirate,
modella-mongo will return instances of modella
models, instead of just
documents. Aside from that, it follows the mquery
API completely.
Example with mquery
User.query().findOne().where({username: 'Bob'}).exec(function(err, u) {
u.username() // => 'Bob'
});
maggregate support
modella-mongo
uses the maggregate
aggregation builder. To use it, simply call Model.aggregate()
.
This allows you to build readable aggregations easily. By default it wraps
responses in Model
instances, but can be disabled by passing skipWrap
as
true
. It also follows the maggregate
api completely.
Example with maggregate
var skipWrapping = true;
User.aggregate(skipWrapping).group({_id: '$location', locationCount: {$sum: 1}}, function(err, res) {
res.forEach(function(loc) {
console.log("In location %s there are %d users", loc._id, loc.locationCount);
});
});
A Note about connection usage
Each call to modella-mongo
will open up a mongo connection, and return a function that can be used as a plugin for ANY Modella model.
As such it is recommended that you export the result of modella-mongo
and then use that for all of your models.
Example using too many connections
models/user.js
...
var mongo = require('modella-mongo')('localhost/my-db');
User.use(mongo);
...
models/post.js
...
var mongo = require('modella-mongo')('localhost/my-db');
Post.use(mongo);
...
In the above example both the User
and Post
model will open a connection to the mongo database.
Example of better way
config/modella-db.js
var mongo = module.exports = require('modella-mongo')('localhost/my-db');
models/user.js
...
var configuredDb = require('../config/modella-db');
User.use(configuredDb);
...
models/post.js
...
var configuredDb = require('../config/modella-db');
Post.use(configuredDb);
...
Here modella-db.js
configures the mongo database, and then both models use it.
License
MIT