Även om jag inte tror att iteration över ett förväntat antal är det "bästa" sättet att göra detta, här är i princip korrigeringarna av vad du försöker göra, med lite hjälp av noden async
bibliotek för flödeskontroll:
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 viktigaste sakerna här är att din .update()
uttalandet bör istället leta efter "events.handled.visibile": false
matchar, och naturligtvis måste du se till att operationerna körs "i serie", annars finns det ingen riktig garanti för att du faktiskt tar tag i dokumentet i ett ändrat tillstånd från föregående .update()
.
async.whilst
hanterar flödeskontrollen så att den väntar på slutförandet av varje .update()
tills nästa körning. När det första logiska påståendet är true
( räknaren utarmad ) och alla .update()
uttalanden körs och slingan släpps till den sista återuppringningen.
Där det är möjligt bör du verkligen använda "Mass"-uppdateringsoperationer som hänvisas till i svaret som du följer a> . Det skickar alla uppdateringar och har en gång och bara ett svar, så överkostnaderna med att vänta på att varje operation ska slutföras elimineras.