特に大規模なコレクションを処理する場合のパフォーマンスを向上させるには、 を使用してください。 Bulk()
バッチでサーバーに操作を送信するための一括更新用のAPI(たとえば、バッチサイズ1000)。これにより、サーバーにすべてのリクエストを送信するわけではないため、パフォーマンスが大幅に向上します(現在のように) forEach()
ループ)が、1000リクエストごとに1回だけであるため、更新が現在よりも効率的かつ迅速になります。
次の例はこのアプローチを示しています。最初の例では、 Bulk()
MongoDBバージョン>= 2.6 and < 3.2
で利用可能なAPI 。 clients
内のすべてのドキュメントを更新します nb_orders_1year
を変更してコレクションを作成する 集計結果の値を持つフィールド。
集計出力コレクションのaggregate()
メソッドは、 cursor
を返します。
、forEach()
var bulk = db.clients.initializeUnorderedBulkOp(),
pipeline = [
{
"$match": { "date_order": { "$gt": v_date1year } }
},
{
"$group": {
"_id": "$id_client",
"count": { "$sum" : 1 }
}
},
{ "$out": "tmp_indicators" }
],
counter = 0;
db.orders.aggregate(pipeline);
db.tmp_indicators.find().forEach(function (doc) {
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "nb_orders_1year": doc.count }
});
counter++;
if (counter % 1000 == 0) {
bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
bulk = db.clients.initializeUnorderedBulkOp();
}
});
// Clean up remaining operations in queue
if (counter % 1000 != 0) { bulk.execute(); }
次の例は、新しいMongoDBバージョン3.2
に適用されます は、バルクを廃止しました。 API
bulkWrite()
。
上記と同じカーソルを使用しますが、結果を繰り返す代わりに、 map()
方法:
var pipeline = [
{
"$match": { "date_order": { "$gt": v_date1year } }
},
{
"$group": {
"_id": "$id_client",
"count": { "$sum" : 1 }
}
},
{ "$out": "tmp_indicators" }
];
db.orders.aggregate(pipeline);
var bulkOps = db.tmp_indicators.find().map(function (doc) {
return {
"updateOne": {
"filter": { "_id": doc._id } ,
"update": { "$set": { "nb_orders_1year": doc.count } }
}
};
});
db.clients.bulkWrite(bulkOps, { "ordered": true });