Ondrej Tokar Ondrej Tokar - 4 months ago 27
Node.js Question

Is it necessary to open MongoDB connection every time I want to work with the DB?

In the example I am working with is this code:

//lets require/import the mongodb native drivers.
var mongodb = require('mongodb');

//We need to work with "MongoClient" interface in order to connect to a mongodb server.
var MongoClient = mongodb.MongoClient;

// Connection URL. This is where your mongodb server is running.
var url = 'mongodb://localhost:27017/my_database_name';

// Use connect method to connect to the Server
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
//HURRAY!! We are connected. :)
console.log('Connection established to', url);

// Get the documents collection
var collection = db.collection('users');

//Create some users
var user1 = {name: 'modulus admin', age: 42, roles: ['admin', 'moderator', 'user']};
var user2 = {name: 'modulus user', age: 22, roles: ['user']};
var user3 = {name: 'modulus super admin', age: 92, roles: ['super-admin', 'admin', 'moderator', 'user']};

// Insert some users
collection.insert([user1, user2, user3], function (err, result) {
if (err) {
console.log(err);
} else {
console.log('Inserted %d documents into the "users" collection. The documents inserted with "_id" are:', result.length, result);
}
//Close connection
db.close();
});
}
});


As you may see, he is doing an operation in the
connect
function. I would like to keep it modular and separate the connection from DB operations.

My suggestion would be to make a singleton on
db
variable and reuse that one. At least that's what I would do in Java to which I am used to.

However, I am not sure as in the example he hasn't suggested anything like that.

Answer

I would recommend against maintaining one connection if you want any kind of scalability.

There are a number of options for connection pooling, etc, but most folks who spend any time at all with Node and MongoDB end up moving to Mongoose at some point.

In addition to adding a nice schema layer, it offers connection abstraction so that you can default to a shared connection by calling mongoose.connect(), or you can create multiple connections or participate in connection pooling by calling mongoose.createConnection(). In both cases, you call it without a callback, and the mongoose machinery will defer subsequent calls to the module until after the connection is established, so that your code doesn't have to care.

Something like your use case might look like so:

// in your app.js or server.js file
var mongoose = require('mongoose');
mongoose.connect(config.db.url); // assuming you have some module that handles config variables

Then in ./models/user.js

const mongoose = require('mongoose'),
         Schema   = mongoose.Schema;

   const UserSchema = new Schema({
      name: String,
      age: Number,
      roles: [String]
   });
   mongoose.model('User',UserSchema);

finally, in lets say a seed function to create your initial batch of users:

const mongoose = require('mongoose'),
      User     = mongoose.model('User');

// create some users
var user1 = new User({name: 'modulus admin', age: 42, roles: ['admin', 'moderator', 'user']});
var user2 = new User({name: 'modulus user', age: 22, roles: ['user']});

user1.save(console.log);
user2.save(console.log);