Selvom jeg ikke tror, at iteration over et forventet antal er den "bedste" måde at gøre dette på, er her grundlæggende rettelserne til det, du forsøger at gøre, med lidt hjælp fra noden async
bibliotek til flowkontrol:
async.waterfall(
[
function(callback) {
collection.aggregate(
[
{ "$match": { "_id": ObjectId("4d2d8deff4e6c1d71fc29a07") } },
{ "$unwind": "$events" },
{ "$match": { "events.handled.visibile": false } },
{ "$group": {
"_id": "$_id",
"count": { "$sum": 1 }
}}
],
callback
);
},
function(results,callback) {
console.log(results);
var result = results[0];
async.whilst(
function() { return result.count-- },
function(callback) {
collection.update(
{ "_id": result._id, "events.handled.visibile": false },
{ "$set": { "events.$.handled.visibile": true } },
callback
)
},
callback
);
}
],
function(err) {
if (err) throw err;
// finished now
}
);
Så de vigtigste ting her er, at din .update()
sætningen skal i stedet lede efter "events.handled.visibile": false
matcher, og du skal selvfølgelig sørge for, at operationerne udføres "i serie", ellers er der ingen reel garanti for, at du faktisk griber dokumentet i en ændret tilstand fra den tidligere .update()
.
async.whilst
håndterer flowkontrollen, så den venter på fuldførelse af hver .update()
indtil den næste udføres. Når det første logiske udsagn er true
( tæller opbrugt ) og alle .update()
sætninger køres, så frigives løkken til det endelige tilbagekald.
Hvor det er muligt, bør du virkelig bruge "Bulk"-opdateringsoperationer som refereret til i svaret, som du følger a> . Det sender alle opdateringer og har én gang og kun ét svar, så overheaden med at vente på, at hver operation er fuldført, er elimineret.