我尝试创建一个mongo连接池工厂,检查是否已存在与mongo的连接并返回连接。如果它没有创建连接池并返回连接。
我希望能够从多个要查询mongo的文件中要求这个。每个文件都应该像这样需要mongo:
var fooMongoFactory = require('../../lib/mongoFactory').init(mongodb://localhost:27017/foo);
然后你在文件中使用它:
fooMongoFactory.getConnection().then(function(db) {
// do stuff
});
我遇到的问题是我希望能够在文件中指定多个不同的mongo实例,但是在执行此操作时,我的第二个init会覆盖第一个。例如:
var fooMongoFactory = require('../../lib/mongoFactory').init(mongodb://localhost:27017/foo);
var barMongoFactory = require('../../lib/mongoFactory').init(mongodb://localhost:27017/bar);
fooMongoFactory.getConnection().then(function(db) {
// querying in here is actually pointing at the mongo db "bar"
});
如何调整我的工厂以便我可以连接到多个不同的mongo实例,以及跨多个文件使用同一个工厂而不必每次都实例化它?我想过使用构造函数,但是会在每个使用mongoFactory的文件中创建一个新的连接池。
/**
* Creates and manages the Mongo connection pool
*
* @type {exports}
*/
var Q = require('q');
var MongoClient = require('mongodb').MongoClient;
var dbPromise = null;
var db = null;
module.exports = function() {
return {
init: function init(connectionString) {
db = connectionString;
return module.exports;
},
/**
* Gets a connection to Mongo from the pool. If the pool has not been instantiated it,
* instantiates it and returns a connection. Else it just returns a connection from the pool
*
* @returns {*} - A promise object that will resolve to a mongo db object
*/
getConnection: function getConnection() {
// get a connection to mongo using the db string and return dbPromise
}
}
}();
答案 0 :(得分:1)
mongodb
节点模块已具有built-in connection pooling功能,当您致电connect()
时,该功能会自动使用。 default max connection pool size is 5,但您可以在连接网址中更改此值(例如'mongodb://localhost:27017/foo?maxPoolSize=15'
)。
您还希望通过将server config options中的poolSize
设置为小于或等于maxPoolSize
的某个值来更改创建的实际连接数。您可能还想将auto_reconnect
设置为true。
现在你可以做的是保持一个对象键在host:port上,该对象包含该服务器的数据库对象。如果有人传入包含对象中host:port的连接字符串,则返回池。否则,创建,缓存并返回新的数据库对象。
答案 1 :(得分:0)
我最终创建了模块,因此您必须传入要连接的mongodb的连接字符串。该模块最终跟踪已经对mongo进行的所有连接以及是否存在与传入的mongodb的当前连接。
/**
* Creates and manages the Mongo connection pool
*
* @type {exports}
*/
var Q = require('q');
var MongoClient = require('mongodb').MongoClient;
var _ = require('underscore');
var connections = [];
var dbPromise = null;
module.exports = function() {
return {
/**
* Gets a connection to Mongo from the pool. If the pool has not been instantiated it,
* instantiates it and returns a connection. Else it just returns a connection from the pool
*
* @returns {*} - A promise object that will resolve to a mongo db object
*/
getConnection: function getConnection(connectionString) {
var def = Q.defer();
// If connectionString is null or undefined, return an error
if(_.isEmpty(connectionString)) {
def.reject('getConnection must contain a first parameter');
return dbPromise = def.promise;
}
// Check if connections contains an object with connectionString equal to the connectionString passed in and set the var to it
var pool = _.findWhere(connections, {connectionString: connectionString});
// If no conneciton pool has been instantiated, instantiate it, else return a connection from the pool
if(_.isUndefined(pool)) {
// Initialize connection once
MongoClient.connect(connectionString, function(err, database) {
if (err) {
def.reject(err);
}
// Add the connection to the array
connections.push({connectionString: connectionString, db: database});
def.resolve(database);
});
} else { // Else we have not instantiated the pool yet and we need to
def.resolve(pool.db);
}
return dbPromise = def.promise;
}
};
}();