2016-10-10 6 views
0

同期メソッド(多数のネストされたfor-loops)で多くのデータセットを生成するNodeJSアプリケーションがあります。これらのデータセットはMongoDBデータベースに保存して、後でそれらをより効果的に検索することになっています。NodeJSはMongoDBに一度だけ書き込みます

私はNodeJSにmongodb - ドライバを使用し、デーモンを実行しています。 DBへの接続は正常に動作しており、デーモンウィンドウによれば、データセットの最初のグループが正常に保存されています。 〜400-600msごとに別のグループがありますが、最初のデータセットの後にMongoDBコンソールに出力がなくなり(エラーでもない)、ファイルサイズが増えないため、書き込み操作がうまくいかないと想定します(私はそれが完全に実行するために複数の日を要するので、それが完了するのを待つことができません)。

NodeJSスクリプトを再起動しても、重複のために最初のキーを保存しなくてもいいですか?私がdbフォルダの内容を削除すると、最初のものが再び保存されます。

これは私のスクリプトの重要な部分であり、私が間違っていたものは何も見つかりませんでした。私は問題が内部ロジック(奇妙な重複チェック/並行して実行されていないなど)に多くあると仮定します。

var MongoClient = require('mongodb').MongoClient, dbBuffer = []; 
MongoClient.connect('mongodb://127.0.0.1/loremipsum', function(err, db) { 
    if(err) return console.log("Cant connect to MongoDB"); 
    var collection = db.collection('ipsum'); 
    console.log("Connected to DB"); 

    for(var q=startI;q<endI;q++) { 
     for(var w=0;w<words.length;w++) { 
      dbBuffer.push({a:a, b:b}); 
     } 
     if(dbBuffer.length) { 
      console.log("saving "+dbBuffer.length+" items"); 
      collection.insert(dbBuffer, {w:1}, function(err, result) { 
       if(err) { 
        console.log("Error on db write", err); 
        db.close(); 
        process.exit(); 
       } 
      }); 
     } 
     dbBuffer = []; 
    } 
    db.close(); 
}); 

更新

  • db.closeが呼び出されないと、接続が挿入されるために何を
  • コールバックを変更しない一括挿入に変更
  • をドロップしません。これは問題になるかもしれません! MongoDBコンソールは挿入プロセスが成功したと伝えますが、ドライバとMongoDBの間の通信が挿入のために適切に動作していないように見えます。
+1

'collection.insert'は、非同期呼び出しであるので、あなたの最終' db.close() 'の呼び出しが完了したものの前に起こるです。 – JohnnyHK

+0

また、これは[Bulk.insert](https://docs.mongodb.com/manual/reference/method/Bulk.insert/)(dbBuffer配列ハックの代わり)の良い使用例です。 –

+0

@JohnnyHK前述のようにこれは実際に複数の日を実行する複数のネストされたループの簡略化された例です。 MongoDBコンソールで、接続が閉じていないことがわかります。フェリペ:あなたの権利と私はそれを試してみませんが、それは本当に大きな違いはありません。 –

答えて

0

私はそれを自分で解決しました。私が持っていた誤解の1つは、すべての挿入トランザクションがMongoDBコンソールで確認され、実際に最初のトランザクションを確認するだけであるか、コマンド間にある程度の時間があることです。挿入プロセスが実際に動作するかどうかを確認するには、しばらくの間スクリプトを実行し、MongoDBがローカルファイル(約30-60秒)にそれをダンプするのを待つ必要があります。

さらに、挿入プロセスはお互いに遅すぎるため、MongoDBはWin10 x64ではこれを正しく処理していないようです。私はArray-Bufferから内部バッファ(コメント参照)に変更し、前のデータを挿入した後にのみプロセスを続けました。

これは簡略化されたコード

db.collection('seedlist', function(err, collection) { 
    syncLoop(0,0, collection); 
    //... 
}); 

function syncLoop(q, w, collection) { 
    batch = collection.initializeUnorderedBulkOp({useLegacyOps: true}); 
    for(var e=0;e<words.length;e++) { 
     batch.insert({a:a, b:b}); 
    } 
    batch.execute(function(err, result) { 
     if(err) throw err; 
     //... 
     return setTimeout(function() { 
      syncLoop(qNew,wNew,collection); 
     }, 0); // Timer to prevent Memory leak 
    }); 
} 
関連する問題