Chociaż nie sądzę, że iteracja w stosunku do oczekiwanej liczby jest „najlepszym” sposobem na zrobienie tego, tutaj są zasadniczo poprawki do tego, co próbujesz zrobić, z pewną pomocą węzła async
biblioteka do kontroli przepływu:
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
}
);
Więc najważniejsze jest to, że twój .update()
Instrukcja powinna zamiast tego szukać "events.handled.visibile": false
pasuje i oczywiście musisz się upewnić, że operacje są wykonywane „w serii”, w przeciwnym razie nie ma żadnej gwarancji, że faktycznie pobierasz dokument w zmienionym stanie z poprzedniego .update()
.
async.whilst
obsługuje kontrolę przepływu tak, że czeka na zakończenie każdego .update()
do czasu wykonania następnego. Kiedy pierwsza logiczna instrukcja jest true
( licznik wyczerpany ) i wszystkie .update()
instrukcje są uruchamiane, a następnie pętla zostanie zwolniona do końcowego wywołania zwrotnego.
Tam, gdzie to możliwe, naprawdę powinieneś używać operacji aktualizacji „Bulk”, jak wspomniano w odpowiedzi, którą obserwujesz . To wysyła wszystkie aktualizacje i ma tylko jedną odpowiedź, dzięki czemu eliminuje się narzut związany z oczekiwaniem na zakończenie każdej operacji.