Mongoose
- hallsofvallhalla
- Site Admin
- Posts: 12023
- Joined: Wed Apr 22, 2009 11:29 pm
Mongoose
Anyone use it with Mongodb and Nodejs? Alternatives?
- Jackolantern
- Posts: 10891
- Joined: Wed Jul 01, 2009 11:00 pm
Re: Mongoose
I have used it a little bit, and have found it pretty simple to work with. As for alternatives, you can use Waterline, which is the ORM of SailsJS, or you could take a look at this list here. It does seem that Mongoose is basically the standard, however.
The indelible lord of tl;dr
Re: Mongoose
I'm using it for a couple projects I've got going, and I also use it at work alongside Sequelize for mySQL. I like it, but tbh I haven't explored any alternatives. Anything specific you wanna know?
w00t
- hallsofvallhalla
- Site Admin
- Posts: 12023
- Joined: Wed Apr 22, 2009 11:29 pm
Re: Mongoose
I just find Mongo to be a bit bloated at times and because I do not use it that often I spend too much time figuring out how to do stuff through nodejs with mongo so looking for something quick and clean.
Re: Mongoose
Well Mongoose is just an ODM built on top of the mongo driver. Mongoose may be more bloat then you need.
That said, I found it pretty quick and easy to set up. I'll give you an example of a model and a query based on that model (this is taken from a project I'm working on, it is currently not complete, so there are some validations and callbacks missing atm):
User model:
That's in /src/models/user.js
And the file that picks it up is /src/models/index.js
Now in app.js I can do:
Does that help?
That said, I found it pretty quick and easy to set up. I'll give you an example of a model and a query based on that model (this is taken from a project I'm working on, it is currently not complete, so there are some validations and callbacks missing atm):
User model:
Code: Select all
var bcrypt = require('bcryptjs');
var notEmtpy = function(val) {
return val && val.length;
};
module.exports = function(mongoose) {
var User = {
name: 'User',
schema: mongoose.Schema({
email: String,
password: { type: String, set: function(pwd) { // encrypt password
var salt = bcrypt.genSaltSync(10); // generate salt
return bcrypt.hashSync(pwd, salt); // encrypt against salt
}},
created: { type: Date, default: Date.now },
updated: { type: Date, default: Date.now },
last_ip: String, // last log in IP, used to check against remember me cookie
current_ip: String, // current log in IP, used to check against remember me
active: { type: Boolean, default: true },
reset_password_token: String,
reset_sent_at: Date
})
};
// instance methods
User.schema.methods = {
passwordMatches: function(pwd) {
return bcrypt.compareSync(pwd, this.password);
}
};
// lifecycle callbacks
User.schema.pre('save', true, function(next, done) {
console.log('User trying to be saved!');
next();
//done(); // that 'true' flag in the pre callback makes it so that the user will not save until all of the lifecycle callbacks have passed done();
// mine is currently commented out so that I don't accidentally save any user records while testing
});
// validation
User.schema.path('email').validate(function(val, fn) {
fn(notEmtpy(val));
}, 'Email cannot be blank.');
User.schema.path('email').validate(function(val, fn) {
// Check only when it is a new user or when email field is modified
if (this.isNew || this.isModified('email')) {
var User = mongoose.model('User');
User.find({ email: val }).exec(function (err, users) {
fn(!err && users.length === 0);
});
} else {
fn(true);
}
}, 'Email already exists.');
User.schema.path('password').validate(function(val, fn) {
fn(notEmtpy(val));
}, 'Password cannot be blank.');
return User;
};
And the file that picks it up is /src/models/index.js
Code: Select all
var fs = require('fs'),
path = require('path'),
Mongoose = require('mongoose'),
lodash = require('lodash'),
mongoose = Mongoose.connect('mongodb://' + config.db.host), // config in my case is a global variable where I can pass environment
db = {};
fs
.readdirSync(__dirname)
.filter(function(file) {
return (file.indexOf('.') !== 0) && (file !== 'index.js');
})
.forEach(function(file) {
var model = require(path.join(__dirname, file))(mongoose);
db[model.name] = mongoose.model(model.name, model.schema);
});
module.exports = lodash.extend({
mongoose: mongoose,
Mongoose: Mongoose
}, db);
Code: Select all
var db = require('./models'),
mongoose = db.mongoose.connection; //load up the DB
// access models with db.User
// for example:
app.post('/sign_in', function(req, res, next) {
db.User.findOne({ 'email': req.param('email') }, function(err, user) {
if (err) {
throw err;
} else if (typeof user == 'undefined' || user === null) {
req.session.errors = { err: "The email or password you entered is incorrect." };
res.redirect(req.headers['referer']); // this plays into my flash messages in my case
} else {
// check password
// logged in, redirect to appropriate page, or do whatever else
}
});
});
//handle mongo errors
mongoose.on('error', console.error.bind(console, 'Mongo Connection Error: '));
//once the mongo connection is open, start the HTTP server
mongoose.once('open', function() {
http.createServer(app).listen(app.get('port'), function() {
// server running!
});
});
w00t
- Jackolantern
- Posts: 10891
- Joined: Wed Jul 01, 2009 11:00 pm
Re: Mongoose
Waterline is definitely lighter than Mongoose, but it doesn't offer as many features. You may even be interested in checking out all of SailsJS.
The indelible lord of tl;dr
- a_bertrand
- Posts: 1536
- Joined: Mon Feb 25, 2013 1:46 pm
Re: Mongoose
Somehow I feel always the black sheep with you guys. I use just the most basic Monogo node.js lib and even if I can't say I'm happy by all this non-sense async call back syntax, I'm still pretty happy by the fact I can simply add as much stuff to my objects as I want.
BTW keep in mind there is some restrictions with Mongo which I wasn't aware:
Arrays cannot have negative index (those will not be stored). And yes I was using it (or trying).
Another thing which may happen less frequently: you can't add your own properties to arrays, those "mixed" objects will not be stored with Mongo.
Beside those limitations, my main drawback with Mongo is the lack of foreign keys which I could use in some cases.
BTW keep in mind there is some restrictions with Mongo which I wasn't aware:
Arrays cannot have negative index (those will not be stored). And yes I was using it (or trying).
Another thing which may happen less frequently: you can't add your own properties to arrays, those "mixed" objects will not be stored with Mongo.
Beside those limitations, my main drawback with Mongo is the lack of foreign keys which I could use in some cases.
Creator of Dot World Maker
Mad programmer and annoying composer
Mad programmer and annoying composer
- hallsofvallhalla
- Site Admin
- Posts: 12023
- Joined: Wed Apr 22, 2009 11:29 pm
Re: Mongoose
the code above is my point. Look at all that code you must write. I want simple query functions and that is it. Save data, pull data, done.
Not the black sheep but rather another valuable point of the conversations.
Not the black sheep but rather another valuable point of the conversations.
- Jackolantern
- Posts: 10891
- Joined: Wed Jul 01, 2009 11:00 pm
Re: Mongoose
Seriously check out Waterline. I think it is what you need. The schemas are very basic, and the querying is about as simple as it gets.hallsofvallhalla wrote:the code above is my point. Look at all that code you must write. I want simple query functions and that is it. Save data, pull data, done.
Not the black sheep but rather another valuable point of the conversations.
You may also want to check out MongoJS, which aims to reduce the number of lines needed by simulating the mongo command-line client in node code.
The indelible lord of tl;dr
- a_bertrand
- Posts: 1536
- Joined: Mon Feb 25, 2013 1:46 pm
Re: Mongoose
Actually mongojs could have been the solution for me. It seems to reduce the number of async calls you need. Yet I'm far from being sure it supports all what I need. For example I do text search which requires a couple of "commands". Not sure if that's supported.
Waterline is for me a no go. Basically because I don't want a schema. The client defines alone most of the data. I know it's not really smart or secure but yet this is what I choose at the moment.
Waterline is for me a no go. Basically because I don't want a schema. The client defines alone most of the data. I know it's not really smart or secure but yet this is what I choose at the moment.
Creator of Dot World Maker
Mad programmer and annoying composer
Mad programmer and annoying composer