EDYTUJ
W pytaniu brakowało szczegółu, że wymagane pole do aktualizacji znajdowało się w rzeczywistości w dokumencie podrzędnym . To znacznie zmienia odpowiedź:
Jest to ograniczenie tego, co możesz ewentualnie zrobić z aktualizacją elementów tablicy. I jest to jasno wyjaśnione w dokumentacji . Głównie w tym akapicie:
Więc o to chodzi. Próbuję zaktualizować wszystkie elementów tablicy w jednej instrukcji, takiej jak ta, nie praca. Aby to zrobić, musisz wykonać następujące czynności.
db.warehouses.find({ "items.qty": { "$gt": 0 } }).forEach(function(doc) {
doc.items.forEach(function(item) {
item.qty = 0;
});
db.warehouses.update({ "_id": doc._id }, doc );
})
Co jest w zasadzie sposobem aktualizowania każdego element tablicy.
Multi ustawienie w .update()
oznacza w wielu „dokumentach”. nie może być stosowane do wielu elementów tablicy. Dlatego obecnie najlepszą opcją jest wymiana całości. Lub w tym przypadku równie dobrze możemy zastąpić całość dokumentu, ponieważ i tak musimy to zrobić.
Dla prawdziwych dane zbiorcze, użyj db.eval() . Ale proszę przeczytać najpierw dokumentacja:
db.eval(function() {
db.warehouses.find({ "items.qty": { "$gt": 0 } }).forEach(function(doc) {
doc.items.forEach(function(item) {
item.qty = 0;
});
db.warehouses.update({ "_id": doc._id }, doc );
});
})
Aktualizuję wszystkie elementy w tablicy w całości kolekcja nie jest prosta.
Oryginał
Prawie dokładnie to, co mówi błąd. Aby użyć operatora pozycyjnego, musisz dopasować coś najpierw. Jak w:
db.warehouses.update(
// query
{
_id:ObjectId('5322f07e139cdd7e31178b78'),
"items.qty": { "$gt": 0 }
},
// update
{
$set:{"items.$.qty":0}
},
// options
{
"multi" : true,
"upsert" : true
}
);
Więc gdzie pasuje warunek określa pozycję elementów, które są mniejsze niż 0 to indeks jest przekazywany do operatora pozycyjnego.
PS :Kiedy mutuje jest prawda oznacza to, że aktualizuje co dokument. Zostaw to false
jeśli masz na myśli tylko jeden . Który jest domyślny.