Въпреки че не мисля, че итерирането на очакван брой е „най-добрият“ начин да направите това, ето основно корекциите на това, което се опитвате да направите, с известна помощ от възела async
библиотека за контрол на потока:
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
}
);
Така че основните неща тук са, че вашият .update()
вместо това операторът трябва да търси "events.handled.visibile": false
съвпада и, разбира се, трябва да се уверите, че операциите се изпълняват "последователно", в противен случай няма реална гаранция, че всъщност хващате документа в променено състояние от предишния .update()
.
async.whilst
обработва контрола на потока, така че да чака завършване на всеки .update()
до изпълнение на следващия. Когато първият логичен израз е true
(броячът е изчерпан) и всички .update()
се изпълняват оператори, след което цикълът ще се освободи до последното обратно извикване.
Където е възможно, наистина трябва да използвате „Групови“ операции за актуализиране, както е посочено в отговора, който следвате . Това изпраща всички актуализации и веднъж и има само един отговор, така че излишното изчакване за завършване на всяка операция е елиминирано.