2014-11-06 38 views
1

對於一個項目,我需要做一些查詢一些的MongoDB數據庫之間進行切換。貓鼬如何連接到許多數據庫

我發現了一些爲例這樣的一個:Mongoose and multiple database in single node.js project

他的答案是完美的工作,但現在我試圖做一個循環,unfortunally它不工作,我得到這個錯誤:

events.js:72 
     throw er; // Unhandled 'error' event 
      ^
Error: failed to connect to [localhost:27017] 
    at null.<anonymous> (/home/user/test_many_db_mongodb/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:549:74) 
    at EventEmitter.emit (events.js:106:17) 
    at null.<anonymous> (/home/user/test_many_db_mongodb/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:150:15) 
    at EventEmitter.emit (events.js:98:17) 
    at Socket.<anonymous> (/home/user/test_many_db_mongodb/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection.js:533:10) 
    at Socket.EventEmitter.emit (events.js:95:17) 
    at net.js:440:14 
    at process._tickCallback (node.js:419:13) 

而且我不明白爲什麼我得到這個錯誤,如果在上述工作的鏈接的例子我的代碼也應該這麼做:

var mongoose = require('mongoose'); 

for (var i = 0; i != 1000; i++) { 
    var conn = mongoose.createConnection('mongodb://localhost/test' + i); 

    conn.on('connected', function() { 
     console.log('Mongoose connected to database'); 

     var Model = conn.model('Model', new mongoose.Schema({ 
      title : { type : String, default : 'model in test database' } 
     })); 

     var newModelA = new Model(); 
     newModelA.save(function(err) { 
      if (err) 
       console.log(err); 
      console.log('save A'); 
     }); 
    }); 
} 

感謝您的幫助。

回答

0

感謝您的幫助。

我都嘗試方式,但它並沒有在我的項目上工作,可能是因爲我沒有告訴你所有的代碼。我覺得這個useDd()方式:

var amqp = require('amqp'); 

var MailParser = require('mailparser').MailParser; 
var mailparser = new MailParser(); 

var mongoose = require('mongoose'); 
var conn = mongoose.createConnection('mongodb://localhost'); 

var count = 1; 

var connection = amqp.createConnection({host: 'localhost'}); 

    connection.on('ready', function() { 
     connection.queue('task_queue', {autoDelete: false, 
             durable: true}, function(queue) { 

      console.log('Waiting for emails. To exit press CTRL+C'); 

      queue.subscribe({ack: true, prefetchCount: 1}, function(message, headers, deliveryInfo, ack) { 
       mailparser.write(message.data.toString('utf-8')); 
       mailparser.end(); 

       ack.acknowledge(); 
      }); 
     }); 
    }); 

mailparser.on("end", function(email_object){ 
    var d = new Date(); // just for be sure the db name is unique for the test 
    var db = conn.useDb('test_'+d.getDate()+'-'+d.getMonth()+'-'+d.getYear()+'_'+d.getHours()+'-'+d.getMinutes()+'-'+d.getSeconds()+'-'+d.getMilliseconds()); 

    var Model = conn.model('Model', new mongoose.Schema({ 
      subject : { type : String }, 
      body : { type : String } 
     })); 
    var newEmail = new Model(); 
    newEmail.subject = email_object.subject; 
    newEmail.body = email_object.body; 
    newEmail.save(function(err) { 
     if (err) console.error(err); 
     console.log(count++); 
    }); 
}); 
1

我認爲這是與循環有問題。因爲循環內的代碼本質上是異步的。所以我用forEach代替for。請看下面的代碼。這對我來說可以。

var mongoose = require('mongoose'), 
 
    arr = [0, 1, 2]; 
 

 
arr.forEach(function(i) { 
 
    var conn = mongoose.createConnection('mongodb://localhost/test' + i); 
 

 
    conn.on('connected', function() { 
 
     console.log('Mongoose connected to database', i); 
 

 
     var Model = conn.model('Model', new mongoose.Schema({ 
 
      title: { 
 
       type: String, 
 
       default: 'model in test database' 
 
      } 
 
     })); 
 

 
     var newModelA = new Model(); 
 
     newModelA.save({ 
 
      name: 'a' 
 
     }, function(err) { 
 
      if (err) 
 
       console.log(err); 
 
      console.log('save A'); 
 
     }); 
 
    }); 
 
});

我做這行的三倍。你也可以做1000次。

+1

'forEach'是同步的,所以這會表現得一樣的OP代碼。 – JohnnyHK 2014-11-10 16:33:43

+0

如果for循環的內部代碼是異步的,則循環將首先執行,然後其中的代碼將執行。所以,在這種情況下,內部代碼將得到2的值(上面的例子)。但是在forEach循環中它不會發生。我已經運行OP的代碼以及我自己的代碼。我請求你運行代碼,你也會得到不同的結果。謝謝。 – 2014-11-10 17:57:47

+0

好的,這將解決共享的'conn'變量問題,但它不能解決OP的'失敗連接'錯誤。這是因爲所有這些連接池都在同步循環中打開。需要一些異步流量控制來解決這個問題。 – JohnnyHK 2014-11-10 18:36:06

1

你,因爲你要創建在其中可耗盡的MongoDB連接的供應同步帶所有1000個數據庫連接池獲得failed to connect錯誤。

所以你需要使用類似的async庫的eachLimit方法來介紹一些異步流控制你的方法:

var mongoose = require('mongoose'); 
var async = require('async'); 

var iterations = []; 
for (var i = 0; i != 1000; i++) { 
    iterations.push(i); 
} 

// Iterate over iterations, allowing no more than 5 async iterations to be 
// outstanding at any one time. 
async.eachLimit(iterations, 5, function(i, callback) { 
    var conn = mongoose.createConnection('mongodb://localhost/test' + i); 

    conn.on('connected', function(err) { 
     console.log('Mongoose connected to database'); 

     var Model = conn.model('Model', new mongoose.Schema({ 
      title : { type : String, default : 'model in test database' } 
     })); 

     var newModelA = new Model(); 
     newModelA.save(function(err) { 
      if (err) 
       console.log(err); 
      console.log('save A'); 

      // Close the connection and tell eachLimit this iteration is 
      // complete by having the close method call the eachLimit callback 
      // when the close completes. 
      conn.close(callback); 
     });  
    }); 
}, function() { 
    console.log('All done!'); 
});