Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 274
Ondrej Tokar Avatar asked Aug 01 '16 08:08

Ondrej Tokar


2 Answers

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);
like image 50
Paul Avatar answered Nov 05 '22 13:11

Paul


I believe maintaining a single connection is the best as mentioned in another thread:

The primary comitter in node-mongodb-native says

You open do MongoClient.connect once when your app boots up and reuse the db object. It's not a singleton connection pool each .connect creates a new connection pool. So open it once an[d] reuse across all requests.

like image 37
Smily Avatar answered Nov 05 '22 13:11

Smily