Mongoose: Cannot connect to multiple databases on different hosts

Created on 12 Feb 2015  路  8Comments  路  Source: Automattic/mongoose

I have a node js app built on express and mongoose. Until now, i was using mongoose.connect(uri, options) to make a db connection. But from now on, i want to be able to connect to multiple databases on multiple hosts. Everything is working fine if i'm on the same host ( i use mongoose.createConnection(uri, options) ). For production databases stored on the same host or for localhost databases everything is fine. The problem appears if i try to connect to one localhost database and one remote database, instead of both on the same host.

DbConnection file:

     this.sharedDbConnection = this.mongooseConnection.createConnection('sharedDb');
     this.defaultDbConnection = this.mongooseConnection.createConnection('mongodb');

MongooseConnection file:

function getConnectionUrl(config) {

    return 'mongodb://' + config.user + ':' + config.password + '@' + config.host + ':' + config.port + '/' + config.dbName;
}

MongooseConnection.prototype.createConnection = function(dbName) {

    var connection = this.mongoose.createConnection(getConnectionUrl(this.config[dbName]), this.mongooseConfig, function(err) {

        if(err) {

            console.log(err);

        } else {

            console.log('connected with createConnection on ', dbName);

        }

    });

    return connection;

};

MongooseConfig file:

{
    server: {
        poolSize:      10,
        socketOptions: {
            keepAlive: 1
        }
    },
    db:     {
        numberOfRetries:  10,
        retryMiliSeconds: 1000
    },
    auth:   false
};

Most helpful comment

So the following standalone script works fine for me on 3.8.23, outputs the correct different docs:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var db = mongoose.createConnection('mongodb://<host1>:27017/gh2673');
var db2 = mongoose.createConnection('mongodb://<host2>:27017/gh2673remote');

var s = new Schema({
  name: String
});

var Model1 = db.model('gh2673', s, 'gh2673');
var Model2 = db2.model('gh2673remote', s, 'gh2673remote');

Model1.findOne({}, function(err, doc) {
  console.log(JSON.stringify(doc));
  Model2.findOne({}, function(err, doc) {
    console.log(JSON.stringify(doc));
  });
});

So I don't think this is a mongoose issue. Can you verify that the above script works on your setup?

Also, how does your DbConnections file relate to ModelFactory? Looks like they're creating entirely separate connections.

All 8 comments

Can you verify that you can connect to the remote db using the mongo shell from the machine mongoose is running on? I want to make sure this is a mongoose's fault and not a network issue :)

I can connect to a remote db. If i put in the config file 2 remote dbs or 2 local dbs, everything is working as expected. Only if i put 2 different hosts i will not be able to access both of them.

Hmm do you get any error messages, or do both connections just hang?

No, i don't get any errors. And the connections are not hanging. One of them is working as expected and the other one just returns an empty array when i make a find request. The last one tries to get the collection from the first one. And in my example feom

And always the broken connection is the first one declared (as they are declared in my example from DbConnections file). Somehow the ip of the host is overwritten or something like that. It seems that it's looking for the correct collection, but on the wrong host.

Can you show me how you're creating your models?

With createModel method from ModelFactory:

function ModelFactory(mongoose, mongooseConnection, Schemas, config) {

    this.config = config;
    this.mongoose = mongoose;
    this.schemas = Schemas;
    this.mongooseConnection = mongooseConnection;

    this.mongodbConnection = this.mongooseConnection.createConnection('mongodb');
    this.currentConnection = this.mongodbConnection;

}

ModelFactory.prototype.getConnection = function (db) {

    db = db || 'mongodb';
    var connection = this[db + 'Connection'];

    if (!connection) {
        throw new Error('invalid db name: ' + db);
    }

    if (this.currentConnection !== connection) {
        if (this.config.mongodb.host !== this.config.sharedDb.host) {

            this[db + 'Connection'] = this.mongooseConnection.createConnection(db);
            connection = this[db + 'Connection'];

        }

        this.currentConnection = connection;
    }

    return connection;

};

ModelFactory.prototype.getSchema = function (modelName) {

    var schema = this.schemas[modelName];

    if (!schema) {
        throw new Error('invalid model name: ' + modelName);
    }

    return schema;

};

ModelFactory.prototype.createModel = function (modelName, db) {

    var schema = this.getSchema(modelName);
    var connection = this.getConnection(db);

    return connection.model(modelName, schema);

};


module.exports = ModelFactory;

So the following standalone script works fine for me on 3.8.23, outputs the correct different docs:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var db = mongoose.createConnection('mongodb://<host1>:27017/gh2673');
var db2 = mongoose.createConnection('mongodb://<host2>:27017/gh2673remote');

var s = new Schema({
  name: String
});

var Model1 = db.model('gh2673', s, 'gh2673');
var Model2 = db2.model('gh2673remote', s, 'gh2673remote');

Model1.findOne({}, function(err, doc) {
  console.log(JSON.stringify(doc));
  Model2.findOne({}, function(err, doc) {
    console.log(JSON.stringify(doc));
  });
});

So I don't think this is a mongoose issue. Can you verify that the above script works on your setup?

Also, how does your DbConnections file relate to ModelFactory? Looks like they're creating entirely separate connections.

Was this page helpful?
0 / 5 - 0 ratings