För förbättrad prestanda, särskilt när du har att göra med stora samlingar, dra fördel av att använda Bulk()
API för massuppdateringar eftersom du kommer att skicka operationerna till servern i omgångar (till exempel en batchstorlek på 1000) vilket ger dig mycket bättre prestanda eftersom du inte kommer att skicka varje begäran till servern (som du för närvarande gör gör med uppdateringssatsen i forEach()
loop) men bara en gång av 1000 förfrågningar, vilket gör dina uppdateringar mer effektiva och snabbare än för närvarande.
Följande exempel visar detta tillvägagångssätt, det första använder Bulk()
API tillgängligt i MongoDB-versionerna >= 2.6 and < 3.2
. Den uppdaterar alla dokument i clients
insamling genom att ändra nb_orders_1year
fält med värden från aggregeringsresultaten.
Sedan Du kan använda aggregeringsutdatasamlingens aggregate()
metod returnerar en cursor
,forEach()
metod för att iterera det och komma åt varje dokument och därmed ställa in massuppdateringsoperationerna i omgångar för att sedan skicka över servern effektivt med API:et:
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(); }
Nästa exempel gäller den nya MongoDB-versionen 3.2
som sedan fasade ut Bulk API
och tillhandahöll en nyare uppsättning apis med bulkWrite()
.
Den använder samma markör som ovan men istället för att iterera resultatet, skapa arrayen med bulkoperationerna genom att använda dess map()
metod:
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 });