2014-11-06 72 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!'); 
});