db2791 db2791 - 4 months ago 68
Node.js Question

Best way to connect to Mongodb using Node

I've read a few guides on how to use Mongo with Node, and they all seem to connect to databases differently. One particular way that worked well for me was:

MongoClient.connect("mongodb://localhost:27017/exampleDb", function(err, db) {
if(err) { return console.dir(err); }

db.createCollection('users', function(err, collection) {});

//Do all server/database operations in here

});


However, this seems inefficient/odd to me, I would have to reconnect to the database every time there is an
app.get()
, like for making a new user or retrieving information.

Another way that seems better suited to me is

var mongoose = require("mongoose")
var db = mongoose.connect("localhost:27107/users");

db.createCollection('users', function(err, collection) {});


I've seen several sites do something along these lines, but I personally can't get the above to work. I keep getting the error
TypeError: db.createCollection is not a function
server-side. So, my question is why the above code doesn't work, if the first code is a good alternative, and if there's any other ways to do this.

Answer

You can use a global variable to hold the connection (e.g. db), for example:

var db = null // global variable to hold the connection

MongoClient.connect('mongodb://localhost:27017/test', function(err,database) {
    if(err) { console.error(err) }
    db = database // once connected, assign the connection to the global variable
})

app.get('/', function(req,res) {
    db.collection('test').find({}).toArray(function(err,docs) {
        if(err) { console.error(err) }
        res.send(JSON.stringify(docs))
    })
})

Or, if you prefer, you can also use the Promise object that is returned by MongoClient if it is called without a callback argument:

var conn = MongoClient.connect('mongodb://localhost:27017/test') // returns a Promise

app.get('/', function(req,res) {
    conn.then(db => db.collection('test').find({}).toArray(function(err,docs) {
        if(err) { console.error(err) }
        res.send(JSON.stringify(docs))
    }))
})

Please note that I used the ES6 fat arrow function definition in the second example.

You are absolutely correct that you should not call MongoClient every time. Using a global variable or Promises allows the MongoDB node.js driver to create a connection pool, which achieves at least two good things:

  • Connections are reused in a pool, so there is no multiple expensive setup/teardown process for the lifetime of your application. You connect once, and let the driver take care of the rest for you.
  • You can control the amount of connection your application makes into the database, by limiting the size of the connection pool.