Ce face findOneAndUpdate()
findOneAndUpdate() găsește un document, îl modifică și ți-l întoarce, fără ca alt client să poată interveni între pași. Implicit primești documentul de dinainte de modificare; cu returnDocument: 'after' primești versiunea nouă.
sort alege care document se modifică atunci când mai multe se potrivesc filtrului, iar projection limitează câmpurile întoarse. Modelul clasic este contorul de numere de factură: $inc + upsert + returnDocument: 'after'. findOneAndDelete() șterge documentul și ți-l întoarce, util pentru cozi simple.
Parametri
| Parametru | Descriere |
|---|---|
returnDocument |
'before' (implicit) sau 'after'. |
sort |
Ordinea în care se alege documentul, dacă se potrivesc mai multe. |
projection |
Câmpurile întoarse. |
upsert |
Creează documentul dacă nu există. |
Ce returnează
Documentul (înainte sau după modificare) sau null dacă nu s-a găsit nimic.
Exemple
Exemplele de pe această pagină pornesc de la datele de mai jos. Rulează mai întâi acest cod, apoi exemplul.
use magazin
db.comenzi.insertMany([
{ _id: 1, client: 'Ana', oras: 'Iași', total: 120, status: 'livrata', produse: ['caiet', 'pix'] },
{ _id: 2, client: 'Dan', oras: 'Cluj', total: 85, status: 'noua', produse: ['carte'] },
{ _id: 3, client: 'Ioana', oras: 'Iași', total: 240, status: 'livrata', produse: ['rucsac', 'caiet', 'pix'] },
{ _id: 4, client: 'Mihai', oras: 'Brașov', total: 60, status: 'anulata', produse: [] }
])
Exemplul 1: Preluarea celei mai vechi comenzi noi
Comanda primește statusul nou și ne este întoarsă deja modificată.
db.comenzi.findOneAndUpdate({ status: 'noua' }, { $set: { status: 'in-livrare' } }, { sort: { _id: 1 }, returnDocument: 'after' })
Ieșire în mongosh
{
_id: 2,
client: 'Dan',
oras: 'Cluj',
total: 85,
status: 'in-livrare',
produse: [ 'carte' ]
}
Exemplul 2: Următorul număr de factură
Contorul crește atomic, deci doi clienți nu primesc niciodată același număr. Aici contorul era deja la 1042.
db.contoare.findOneAndUpdate({ _id: 'factura' }, { $inc: { valoare: 1 } }, { upsert: true, returnDocument: 'after' })
Ieșire în mongosh
{ _id: 'factura', valoare: 1043 }
Exemplul 3: Ștergere cu întoarcerea documentului
findOneAndDelete întoarce documentul șters, ca să-l poți arhiva sau afișa.
db.comenzi.findOneAndDelete({ status: 'anulata' }, { projection: { client: 1, total: 1 } })
Ieșire în mongosh
{ _id: 4, client: 'Mihai', total: 60 }
Greșeli frecvente
- Uiți
returnDocument: 'after'și te miri că documentul întors are valorile vechi. - Fără
sort, nu știi care document va fi ales când filtrul se potrivește mai multora. - Driverele mai vechi întorceau un obiect
{ value, ok }; mongosh și driverele actuale întorc direct documentul.
Comenzi înrudite
upsert: true și $setOnInsert: Cu upsert: true, updateOne actualizează documentul găsit sau, dacă nu există, îl creează; $setOnInsert scrie câmpuri doar la creare.replaceOne(): Înlocuiește complet primul document găsit cu un document nou; câmpurile care nu apar în documentul nou dispar.bulkWrite(): Trimite mai multe operații de scriere (inserări, actualizări, ștergeri) către o colecție într-o singură cerere.$currentDate: Operatorul $currentDate pune în câmp data și ora serverului în momentul actualizării, ca Date sau ca Timestamp.