2014-08-28 53 views
1

我想创建一个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" 
}); 

我如何调整我的工厂,这样我可以连接到蒙戈的多个不同的实例,以及使用在多个文件这同一个工厂,而不必每次都实例化了吗?我想过使用构造函数,但是它会在每个使用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 
    } 
    } 
}(); 
+1

凡/如何'init'叫什么名字? – 2014-08-28 21:18:13

+0

在需要mongoFactory后调用Init。 Init只是设置调用脚本调用getConnection时使用的db变量。 'getConnection'使用之前设置的'db'变量。 – Catfish 2014-08-28 21:28:36

+0

只是命名“工厂”并不能使它成为工厂。 http://en.wikipedia.org/wiki/Factory_method_pattern – 2014-08-28 21:30:45

回答

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; 
    } 
    }; 
}(); 

https://github.com/toymachiner62/mongo-factory

1

mongodb节点模块已经有了,当你调用connect()时自动使用built-in connection pooling功能。 default max connection pool size is 5,但是您可以在连接URL中更改此值(例如'mongodb://localhost:27017/foo?maxPoolSize=15')。

您还需要更改通过在server config options中将poolSize设置为小于或等于maxPoolSize的某个值创建的实际连接数。您可能还想将auto_reconnect设置为true。

现在你可以做的是保持一个对象在主机上:包含该服务器的数据库对象的端口。如果有人传入包含主机端口的连接字符串,则返回该池。否则,创建,缓存并返回新的数据库对象。

+0

我知道它内置了连接池,但是如果你有两个文件,每个文件都会调用'connect()'来创建2个连接。我试图通过创建这个mongoFactory来避免这种情况。一个用例是有一个网页,可以对我的后端进行多个Web服务调用。那么,如果每个Web服务调用都调用调用'connect()'的不同文件,那么现在我打开了多个连接池。 – Catfish 2014-08-28 23:27:35