$out / $merge în MongoDB & NoSQL

Etapele $out și $merge salvează rezultatul unei agregări într-o colecție: $out o înlocuiește complet, $merge o actualizează.

Sintaxă
{ $out: <colectie> }
{ $merge: { into: <colectie>, on: <camp>, whenMatched: 'replace' | 'merge' | 'keepExisting' | 'fail' | [ ... ], whenNotMatched: 'insert' | 'discard' | 'fail' } }

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 $merge cu alt câmp decât _id în on, 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.
Comunitate & Schimb de cunoștințe

Întrebări & Exemple de Cod: $out / $merge

Ai o nelămurire despre utilizarea comenzii $out / $merge sau ai descoperit un truc / fragment de cod util? Distribuie-l cu ceilalți programatori!

💬

Fii primul care pune o întrebare sau distribuie un fragment de cod / prompt!

Nu au fost adăugate încă întrebări sau exemple de cod pentru această pagină. Dacă ai întâlnit o problemă sau ai un snippet util, adaugă-l mai jos pentru a-i ajuta pe ceilalți.

Comunitate Adaugă o întrebare sau distribuie un cod

Moderare & Siguranță:

Pentru a menține calitatea și securitatea informațiilor, fiecare întrebare sau fragment de cod/prompt este analizat (manual sau prin moderare asistată de AI) înainte de publicare.