Ce face $out / $merge
$out (MongoDB 2.6+) scrie rezultatul agregării într-o colecție, înlocuind complet conținutul ei. Este util pentru rapoarte recalculate integral, de exemplu o dată pe noapte.
$merge (MongoDB 4.2+) combină rezultatul cu o colecție existentă, document cu document: pe baza câmpului on (implicit _id) decide ce face când găsește un document (whenMatched) și când nu găsește (whenNotMatched). Așa poți actualiza incremental statistici, fără să recalculezi tot. Ambele trebuie să fie ultima etapă din pipeline și nu întorc documente în mongosh.
Parametri
| Parametru | Descriere |
|---|---|
$out |
Numele colecției care va fi înlocuită. |
into |
Colecția destinație pentru $merge (poate fi și în altă bază: { db, coll }). |
on |
Câmpul (sau câmpurile) de potrivire; are nevoie de index unic. |
whenMatched |
'merge' (implicit), 'replace', 'keepExisting', 'fail' sau un pipeline. |
whenNotMatched |
'insert' (implicit), 'discard', 'fail'. |
Ce returnează
Nimic în mongosh (cursor gol); rezultatul se citește apoi din colecția destinație.
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: Raport complet recalculat cu $out
Prima comandă nu afișează nimic; raportul se citește din colecția nouă.
db.comenzi.aggregate([{ $group: { _id: '$oras', total: { $sum: '$total' } } }, { $out: 'vanzari_pe_oras' }])
db.vanzari_pe_oras.find().sort({ total: -1 })
Ieșire în mongosh
magazin> db.comenzi.aggregate([{ $group: { _id: '$oras', total: { $sum: '$total' } } }, { $out: 'vanzari_pe_oras' }])
magazin> db.vanzari_pe_oras.find().sort({ total: -1 })
[
{ _id: 'Iași', total: 360 },
{ _id: 'Cluj', total: 85 },
{ _id: 'Brașov', total: 60 }
]
Exemplul 2: Statistici pe client actualizate cu $merge
Documentele existente sunt îmbinate, cele noi sunt inserate; restul colecției rămâne.
db.comenzi.aggregate([{ $group: { _id: '$client', totalCumparat: { $sum: '$total' } } }, { $merge: { into: 'statistici_clienti', whenMatched: 'merge', whenNotMatched: 'insert' } }])
db.statistici_clienti.findOne({ _id: 'Ana' })
Ieșire în mongosh
magazin> db.comenzi.aggregate([{ $group: { _id: '$client', totalCumparat: { $sum: '$total' } } }, { $merge: { into: 'statistici_clienti', whenMatched: 'merge', whenNotMatched: 'insert' } }])
magazin> db.statistici_clienti.findOne({ _id: 'Ana' })
{ _id: 'Ana', totalCumparat: 120 }
Greșeli frecvente
$outșterge tot ce era în colecția destinație. Dacă vrei să păstrezi datele vechi, folosește$merge.- La
$mergecu alt câmp decât_idînon, colecția destinație trebuie să aibă un index unic pe acel câmp.
Comenzi înrudite
$group: Etapa $group grupează documentele după o cheie și calculează totaluri: $sum, $avg, $min, $max, $push, $addToSet.$addFields / $set: Etapa $addFields (alias $set) adaugă câmpuri calculate sau suprascrie câmpuri existente, păstrând restul documentului.createIndex() cu unique: true: Un index unic garantează că două documente nu pot avea aceeași valoare într-un câmp, de exemplu același email.