Както споменахме, основният проблем тук е с актуализациите на множество елементи с позиционния оператор, както е записано в този дългогодишен проблем:http://jira.mongodb.org/browse/SERVER-1243
Следователно основният случай е, че нито едно изпълнение не може да направи това, така че за да обработите множество елементи от масив, имате нужда от някакъв метод за определяне колко елемента трябва да актуализирате и да обработите един оператор за актуализиране за всеки елемент.
Опростен подход към това обикновено се използва Групови операции за да обработите това, което в крайна сметка е "множество" операции за актуализиране като една заявка и отговор към сървъра:
var bulk = db.collection.initializeOrderedBulkOp(),
count = 0;
db.collection.find({ "name": "John Doe", "adds.status": "PENDING" }).forEach(function(doc) {
doc.adds.filter(function(add){ return add.status = "PENDING" }).forEach(function(add) {
bulk.find({ "_id": doc._id, "adds.status": "PENDING" }).updateOne({
"$set": { "adds.$.status": "APPROVED" }
});
count++;
// Execute once in 1000 statements created and re-init
if ( count % 1000 == 0 ) {
bulk.execute();
bulk = db.collection.initializeOrderedBulkOp();
}
});
});
// Execute any pending operations
if ( count % 1000 != 0 )
bulk.execute();
Ако вашите актуализирани документи са доста малки или наистина са само един документ, тогава можете да се откажете от count
проверете и просто добавете всички групови актуализации в необходимите цикли и просто изпълнете веднъж в края на всички цикли.
По-дълго обяснение и алтернативи можете да намерите на Как да актуализирате множество елементи от масив
, но всички се свеждат до различни подходи за съпоставяне на елемента за актуализиране и обработка на позиционен $
актуализирайте многократно или за всеки съответстващ документ, или докато няма повече върнати модифицирани документи.