2014-11-06 10 views
1

Для проекта мне нужно переключиться между некоторыми базами данных MongoDB для выполнения некоторых запросов.Mongoose как подключиться ко многим базам данных

Я нашел несколько Exemple как один на один: 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

+0

В случае цикла цикла, когда внутренний код является асинхронным, цикл будет выполняться первым, тогда код внутри него будет выполняться. Таким образом, внутренний код получит в этом случае значение 2 (пример выше). Но в случае цикла forEach этого не произойдет. Я запустил код OP, а также свой собственный код. Я прошу вас запустить код, который вы также получите. Спасибо. –

+0

ОК, это исправит общую переменную 'conn', но не устраняет ошибки' 'uns connect '. Это происходит из-за того, что все 1000 из этих пулов соединений открываются в синхронном цикле. Для борьбы с этим требуется некоторое управление потоком асинхронного потока. – JohnnyHK

1

Вы получаете ошибку failed to connect, потому что вы создаете все 1000 пулов подключения к базе данных в синхронном цикле, который исчерпывает поставку доступных соединений MongoDB.

Так что вам нужно ввести некоторые асинхронное управление потоком для вашего подхода, используя нечто вроде eachLimit метода async библиотеки:

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!'); 
});