rob_hicks
rob_hicks

Reputation: 1734

How to make mongoose connection available globally

I am using express 3.x and mongoose 3.6.4.

So far I have been creating a mongoose connection in my express apps.js file like this:

var mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1:27017/mytest');

And then I have separated my models into separate files like models/user as follows:

var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;

var userSchema = new Schema({
userId: ObjectId,
givenName:String ...
});

exports.User = mongoose.model('User', userSchema);

And then in multiple routing files, I have used the User model like so:

var User = require('./models/user').User;
User.findById(id, function(err, user){ ...

This has worked well for local development. All of the models share the same connection.

But now I would like to use mongoose.createConnection() and create a connection pool that can be used in a similar manner. I would like to establish a connection pool when the app starts and use the pool for all models. So, I have tried this:

var conn = mongoose.createConnection("localhost","dpatest", 27017,{user:"???",pass:"???"});

But the models don't automatically share the connection. So, I have tried various things such as export the connection and trying to consume it in the models. But nothing has worked other than setting up a separate connection for each model.

Can someone explain how creating a single connection pool can be done using mongoose.createConnection()?

Here's more info on my question:

/************ app.js *****************/
var http = require('http');
var path = require('path');
var express = require('express');
//these are my routing files
var auth = require('./src/auth');
var profile = require('./src/profile');
var admin = require('./src/admin');
var tx = require('./src/tx');
var system = require('./src/system');
var servicing = require('./src/servicing');

var dbUri;
var dbUser = "?????";
var dbPass = "?????";

//here are my configurations for development and production
app.configure('development', function(){
    app.set('port', 3460);
    app.use(express.errorHandler());
    dbUri = "mongodb://mongodb://127.0.0.1:27017/dpatest";
});

app.configure('production', function(){
    app.set('port', 3461);
    dbName = 'dpa';
    dbUri = "mongodb://"+dbUser+":"+dbPass+"@ds052525.mongolab.com:51437/dpa";
});

/*
this is what I was originally using for development
and want to change for deployment
*/
mongoose.connect(dbUri);

This was what I was planning on moving to:

var conn = mongoose.createConnection(dbUri);

My models (5 different models) are in a directory named src/models from the root of the app. For example the user model:

/************ user.js *************/
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var userSchema = new Schema({
    userId: ObjectId,
    givenName: String, ...
});

which was being exported as follows:

exports.User = mongoose.model('User', userSchema);

Then, models are used in the various routing files like so:

/****************auth.js**************/
var User = require('./models/user').User;

exports.createAccount = function(req, res){
    var user = new User({});
    . . . 
    user.save(function(err, usr){

    });
};

I'm looking for a concrete example of how to replace mongoose.connect() with mongoose.createConnection and get it to work accross multiple modules. Sergey's answer looks promising but I don't understand how to reference the model in a routing file. I tried:

var User = require(../models).User

But couldn't get it to work. It keeps throwing a reference error.

Thanks!

Upvotes: 16

Views: 17635

Answers (4)

TBE
TBE

Reputation: 1133

I know it has been a while, but i have found this article and i was wondering what you guys think about it, it looks elegant. https://productbuilder.wordpress.com/2013/09/06/using-a-single-global-db-connection-in-node-js/

It basically say to use Node.js global.varName mechanism to share the connection globally.

BTW, i have tried it my self, and it worked seamlessly.

Upvotes: 4

Alex Shtafinskiy
Alex Shtafinskiy

Reputation: 31

I hope this is resolved by now, but just in case somebody finds it helpful. In short changing to

var conn = mongoose.createConnection(..)

Requires that all Schemas are registered for this connections. Meaning, instead of User = mongoose.model(...) you need User = db.model(...)

More details with links here: diff between .createConnection vs .connect

Upvotes: -1

regretoverflow
regretoverflow

Reputation: 2153

This sample project on GitHub is a brilliantly simple way to accomplish your goal. It's elegant and effective: https://github.com/fbeshears/register_models. The main code is:

(function(){
  module.exports = function(){
    var mongoose = require('mongoose');
    var Schema = mongoose.Schema; 
    var files = ['kitten.js', 'comments.js'];
    var fn = 0;
            for(fn in files) {
            var path_fn = "./" + files[fn];
            var exported_model = require(path_fn);
            exported_model(mongoose, Schema);
        }

    };
})();

I make a dir called 'models' under my main app dir and put this in the folder and require it, then call register_models();

Upvotes: 2

Sergey Benner
Sergey Benner

Reputation: 4431

in your models folder create index.js

e.g.

    module.exports = function (mongoose,  dbconn) {
        return {

            modelname:  require("./file" )(mongoose, dbconn),
            modelname2:  require("./file2" )(mongoose,  dbconn),
   };
};

then load it in your main startup file file where you create your db connection via

var models    = require("./models")(mongoose,dbconn);

the example model file in the models folder should look something like this:

module.exports = function (mongoose,  dbconn) {
    /*
     * 
     */
    var schema = new mongoose.Schema({
        /**
         * field
         * @type String
         */
        field: String......
      });

  return dbconn.model("modelname", schema, "collectioname");
};

and so on....

Upvotes: 4

Related Questions