1. ホーム
  2. javascript

[解決済み] NodejsでMongoDBデータベース接続を終了するとき

2023-04-27 01:20:59

質問

NodejsとNode MongoDBネイティブドライバを介してMongoDBで作業しています。いくつかのドキュメントを取得し、変更を加え、それらをすぐに戻って保存する必要があります。これは例です。

db.open(function (err, db) {
  db.collection('foo', function (err, collection) {
    var cursor = collection.find({});
    cursor.each(function (err, doc) {
      if (doc != null) {
        doc.newkey = 'foo'; // Make some changes
        db.save(doc); // Update the document
      } else {
        db.close(); // Closing the connection
      }
    });
  });
});

非同期のため、文書の更新処理に時間がかかる場合、カーソルが文書の末尾に達すると、データベース接続が切断されます。すべての更新がデータベースに保存されるわけではありません。

もし db.close() が省略された場合、すべてのドキュメントは正しく更新されますが、アプリケーションはハングアップし、終了することはありません。

私は、更新の数を追跡するためにカウンターを使用することを提案するポストを見ました、ゼロにフォールバックしたとき、それからデータベースを閉じます。しかし、私はここで何か間違ったことをしているのでしょうか? このような状況を処理する最良の方法は何でしょうか? 次のようになります。 db.close() はリソースを解放するために使用されなければならないのでしょうか?それとも、新しいデータベース接続を開く必要があるのでしょうか?

どのように解決するのですか?

カウント方式に基づく解決策を紹介します(テストはしていませんし、エラートラップもありませんが、アイデアは伝わるはずです)。

基本的な戦略は次のとおりです。更新が必要なレコード数のカウントを取得し、各レコードを非同期に保存し、成功時にコールバックでカウントをデクリメントし、カウントが 0 に達した場合 (最後の更新が終了したとき) に DB を閉じます。を使うことで {safe:true} を使用することで、各更新が成功することを保証できます。

mongoサーバーは1つの接続につき1つのスレッドを使用するので、a) 未使用の接続を閉じるか、b) 接続をプールして再利用するのがよいでしょう。

db.open(function (err, db) {
  db.collection('foo', function (err, collection) {
    var cursor = collection.find({});
    cursor.count(function(err,count)){
      var savesPending = count;

      if(count == 0){
        db.close();
        return;
      }

      var saveFinished = function(){
        savesPending--;
        if(savesPending == 0){
          db.close();
        }
      }

      cursor.each(function (err, doc) {
        if (doc != null) {
          doc.newkey = 'foo'; // Make some changes
          db.save(doc, {safe:true}, saveFinished);
        }
      });
    })
  });
});