За подобрена производителност, особено когато работите с големи колекции, се възползвайте от използването на Bulk()
API за групови актуализации, тъй като ще изпращате операциите до сървъра на партиди (например, да кажем размер на партида от 1000), което ви дава много по-добра производителност, тъй като няма да изпращате всяка заявка до сървъра (както сте в момента правейки с израза за актуализиране в forEach()
цикъл), но само веднъж на всеки 1000 заявки, като по този начин вашите актуализации стават по-ефективни и по-бързи, отколкото в момента.
Следните примери демонстрират този подход, като първият използва Bulk()
API, наличен във версии на MongoDB >= 2.6 and < 3.2
. Той актуализира всички документи в clients
събиране чрез промяна на nb_orders_1year
полета със стойности от резултатите от обобщаването.
Тъй като Можете да използвате колекцията от агрегирани изходни данни aggregate()
метод връща cursor
,forEach()
метод за итерация и достъп до всеки документ, като по този начин се настройват операциите за групово актуализиране на партиди, които след това се изпращат през сървъра ефективно с API:
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
и предостави по-нов набор от 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 });