Pro lepší výkon, zejména při práci s velkými kolekcemi, využijte výhod Bulk()
API pro hromadné aktualizace, protože operace budete posílat na server v dávkách (například řekněme o velikosti dávky 1000), což vám poskytuje mnohem lepší výkon, protože nebudete na server posílat každý požadavek (jako v současnosti dělat s prohlášením o aktualizaci v rámci forEach()
smyčka), ale pouze jednou z 1 000 požadavků, takže vaše aktualizace jsou efektivnější a rychlejší než v současnosti.
Následující příklady demonstrují tento přístup, první používá Bulk()
API dostupné ve verzích MongoDB >= 2.6 and < 3.2
. Aktualizuje všechny dokumenty v clients
sběr změnou nb_orders_1year
pole s hodnotami z výsledků agregace.
Od Můžete použít aggregate()
metoda vrací cursor
,forEach()
metoda pro jeho iteraci a přístup ke každému dokumentu, čímž se nastaví operace hromadné aktualizace v dávkách, aby se pak efektivně posílaly přes server pomocí 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(); }
Další příklad platí pro novou verzi MongoDB 3.2
která od té doby zastarala hromadnou API
a poskytla novější sadu API pomocí bulkWrite()
.
Používá stejný kurzor jako výše, ale místo iterace výsledku vytvořte pole s hromadnými operacemi pomocí jeho map()
metoda:
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 });