2017-06-18 14 views
0

原因次のスクリプトNodejsループとMongoDBの保存MongoDBの最大接続

var startPage = 1 
var endPage = 40 



for (y = startPage; y < endPage ; y++) { 

var y = Number(y) 
var search = getresult.from.Myapiforexample 

search.run().then(function (data) { 

    ////////////////// 

    /// This will generate 35 results// 

     var myresult = data.results 



    for (i = 0; i < myresult.length; i++) { 
      data.results[i].getDetails().then(function (details) { 

       savetodb(details) 

      }, function (err) { 
       console.error(err); 
      }); 
    } 

}, function (err) { 
    console.error(err); 
}); 

} 




function savetodb(json) { 

    var getsession = function(db, callback) { 
      var collection = db.collection('thebase'); 

       collection.insert(data, function (err, docs) { 
       callback(docs); 
       db.close(); 
       }); 
     }; 
     MongoClient.connect(url, function(err, db) { 
      getsession(db, function(docs) { 


       console.log("Recording ok") 


      }); 
     }); 

} 

(Yとの)第一ループは、それぞれが35件の結果を生成する40時間を実行して想像してみてください。 Mongo db に保存する40個のX 35レコードがmongodb Maxx接続に届きます。 ので、私は何を探していますは、次のとおりです。

は空の配列

var myarray = [] // ok 

push each "details" to myarray 

myarray.push(details) 

を作成しかしnodeJSが非同期であるように私の問題があり、私はに保存するには、yループの終了を待つ必要があります。 db

どうすればmyarrayを保存関数に送る前にYループが終了するのを待つことができますか? 待機時間を補うことなく..?

私はあなたがPromise.allを使用することができます。..コールバック、任意の成功なしの約束を使用して

+0

y = yがすでに数値であるため、Number(y)は不必要です... –

答えて

0

を試してみました。配列の最初の店舗での約束:

var promises=[]; 
//in the loop 
promises.push(data.results[i].getDetails()); 

だから今、あなたはそれらのすべてを待って、それらを保存することができます

Promise.all(promises).then(savetodb);//passes all results to savetodb in an array 

あなたは、引数として配列を取るためにsavetodbを有効にすることができますが、代わりに、すべての操作のために新しい接続を開くのが...あなた次第


のthats、あなたは単純に保つことができる1:

var db=new Promise(function(res,rej){//in global scope 
MongoClient.connect(url, function(err, db) { 
    if(err) return rej(err); 
    res(db); 
}); 
}); 

今、あなたはどこにでも、この接続にアクセスすることができます:あなたは、このようにエラー処理を実装することができます

db.then(function(db){ 
    //db is our database 
}); 

db.catch(function(err){ 
    console.log("fatal db error. shutting down. "+err); 
    process.exit(); 
}); 
0

非常に複雑なものを。私はそれをテストすることができないので、これがうまくいくことを願っています。私は基本的にあなたのケースでは、私は必要であると考えてPromise.all秒、ネストされたの多用ます

var startPage = 1; 
var endPage = 40; 

var searchPromises = []; 

// make the searches 
for (var y = startPage; y < endPage; y++) { 
    searchPromises.push(getresult.from.Myapiforexample.run()); 
} 

// create a database connection 
new Promise(function (resolve, reject){ 
    MongoClient.connect(url, function(error, database) { 
    if (error) { 
     return reject(error); 
    } 
    resolve(database); 
    }); 
}).then(function (db) { 
    var collection = db.collection('thebase'); 
    Promise.all(searchPromises).then(function (dataArray) { 
    // dataArray contains an array of an array of search results 
    var results = dataArray.map(function (data) { 
     // data contains an array of search results 
     return data.results.map(function (result) { 
     return result.getDetails(); 
     }); 
    }); 
    // results is an array of arrays, flatten it: 
    var resultPromises = [].concat.apply([], results); 
    return Promise.all(resultPromises); 
    }).then(function (results) { 
    var insertPromises = results.map(function (result) { 
     return new Promise(function (resolve, reject) { 
     collection.insert(result, function (error, docs) { 
      if (error) { 
      reject(error); 
      } 
      resolve(docs); 
     }); 
     }); 
    }); 
    return Promise.all(insertPromises); 
    }).then(function (docsArray) { 
    // docsArray contains an array of the docs parameter of the callback in collection.insert 
    console.log('All recordings OK.'); 
    }).catch(function (error) { 
    console.log('Could not insert data into database', error); 
    }); 
}).catch(function (error) { 
    console.log('Could not connect to database', error); 
}); 

この道を、あなたは40倍35データベースconntectionsを作成する必要はありません。

0

あなたはこのために単なる事実の最大接続エラーが発生します:

function savetodb(json) { 

    var getsession = function(db, callback) { 
     var collection = db.collection('thebase'); 

     collection.insert(data, function (err, docs) { 
     callback(docs); 
      db.close(); 
     }); 
    }; 
    MongoClient.connect(url, function(err, db) { 
     getsession(db, function(docs) { 

     console.log("Recording ok") 


     }); 
    }); 
} 

、毎回あなたがこのgetsession関数を呼び出し、あなたはMongoDBのための新しい接続を開きます。また、getsessionと呼び出すと、(endPage - startPage) * (data.results.length)回になります。これは、mongodbインスタンスが受け入れる最大接続数を超えています。あなたは何をすべき

は次のとおりです。

あなたはグローバル変数にdbを保存し、あなたのプログラムの開始時に一度MongoClient.connectを行うと、あなたはMongoClient.connectの実行を終了した後にのみ、あなたのデータを挿入を開始し、そうでないはずですプログラムが実行されている間はdbを閉じてください。

これはこれを行う方法の1つです。

しかし、一方的な方法は生産のためにスケールアップされません。本番環境では、接続プールを使用する必要があります。意味:

  1. あなたのプログラムの開始時に、あなたは回数をMongoDBは、配列内の各dbを保存するために接続します。
  2. 挿入を行うと、配列からdbが得られます
  3. 挿入が完了したら、dbを配列に戻します。
  4. dbがアレイに存在しない場合は、利用可能になるまで待機します。

私は、mongodbで利用可能ないくつかの接続プールの実装があると思います。ちょうど1つを選ぶ。

関連する問題