$out dan $merge: Menulis Hasil Saluran Paip
Pelajar akan menghalakan output agregasi ke dalam koleksi baharu atau sedia ada menggunakan $out dan $merge untuk ETL serta paparan terwujud.
$out dan $merge: Menulis Hasil Saluran Paip ialah pelajaran MongoDB Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran MongoDB Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus MongoDB Academy merangkumi sejumlah 4 pelajaran.
Menulis Hasil Saluran Paip ke dalam Koleksi
Secara lalai, hasil saluran paip pengagregatan dikembalikan kepada klien sebagai kursor. Kadangkala anda mahu menyimpan hasil secara kekal ke dalam koleksi MongoDB untuk digunakan kemudian sebagai pandangan terwujud, cache pelaporan atau sasaran ETL. MongoDB menyediakan dua peringkat untuk tujuan ini: $out, yang menggantikan koleksi sasaran secara atomik, dan $merge, yang melakukan upsert atau menggabungkan hasil ke dalam koleksi sedia ada.
Peringkat $out
$out menulis semua dokumen output saluran paip ke dalam koleksi baharu atau sedia ada melalui operasi atomik. Jika koleksi sasaran wujud, $out menggantikannya sepenuhnya dengan hasil baharu—koleksi lama digugurkan dan koleksi baharu mengambil tempatnya secara atomik. Jika koleksi itu tidak wujud, MongoDB akan menciptanya. $out mesti menjadi peringkat terakhir dalam saluran paip dan tidak mengembalikan apa-apa kepada klien.
// Materialise monthly sales summary into its own collection
db.orders.aggregate([
{ $match: { status: 'completed' } },
{ $group: {
_id: {
year: { $year: '$createdAt' },
month: { $month: '$createdAt' }
},
totalRevenue: { $sum: '$amount' },
orderCount: { $sum: 1 }
}},
{ $sort: { '_id.year': 1, '_id.month': 1 } },
{ $out: 'monthly_sales_summary' } // last stage, writes to collection
]);Jaminan Keatomikan $out
$out menyediakan penggantian atomik: ia menulis semua hasil ke koleksi sementara terlebih dahulu, kemudian menamakan semula koleksi sementara itu kepada nama sasaran dalam satu operasi atomik. Ini bermakna pembaca koleksi sasaran sentiasa melihat sama ada data lama yang lengkap atau data baharu yang lengkap—tidak pernah hasil separa. Oleh itu, $out selamat digunakan dalam persekitaran produksi untuk menyegarkan koleksi pelaporan setiap hari.
// Readers of 'monthly_sales_summary' always see complete data
// Even while $out is running, they see the previous full snapshot
// Only after $out completes does the new snapshot become visible
// Scheduled nightly refresh pattern:
// 1. Run at midnight: aggregate([...stages..., { $out: 'sales_report' }])
// 2. During the day: app reads from 'sales_report' (fast, pre-computed)
// 3. Next midnight: repeat
db.orders.aggregate([
...stages,
{ $out: 'sales_report' } // atomic swap
]);$out ke Pangkalan Data Lain
Sejak MongoDB 4.4, $out menyokong sintaks objek yang membolehkan anda menulis ke koleksi dalam pangkalan data lain. Nyatakan kedua-dua db (nama pangkalan data) dan coll (nama koleksi) dalam bentuk objek. Ini berguna untuk mengasingkan pangkalan data operasi dan pelaporan dalam kelompok yang sama.
// Write to a collection in a different database
db.orders.aggregate([
{ $match: { status: 'completed' } },
{ $group: { _id: '$region', revenue: { $sum: '$amount' } } },
{
$out: {
db: 'reporting', // target database
coll: 'regional_revenue' // target collection
}
}
]);
// Result is in reporting.regional_revenuePeringkat $merge
Diperkenalkan dalam MongoDB 4.2, $merge lebih fleksibel daripada $out: bukannya menggantikan koleksi sasaran, ia melakukan upsert bagi setiap dokumen output ke dalam sasaran. Anda mentakrifkan kunci gabungan (medan yang mengenal pasti dokumen sedia ada), kemudian MongoDB menentukan sama ada setiap dokumen output perlu dimasukkan, dikemas kini, digantikan, menyebabkan kegagalan atau mengekalkan dokumen sedia ada.
// Upsert daily stats into a persistent stats collection
db.events.aggregate([
{ $group: {
_id: {
date: { $dateToString: { format: '%Y-%m-%d', date: '$timestamp' } },
eventType: '$type'
},
count: { $sum: 1 }
}},
{
$merge: {
into: 'daily_event_stats',
on: ['_id'], // match key
whenMatched: 'replace', // update matching docs
whenNotMatched: 'insert' // insert new docs
}
}
]);Pilihan $merge whenMatched
Pilihan whenMatched mengawal perkara yang berlaku apabila dokumen output saluran paip sepadan dengan dokumen sedia ada dalam koleksi sasaran. Pilihannya ialah: 'replace' — menulis ganti dokumen sedia ada; 'merge' — menggabungkan medan (medan sedia ada yang tiada dalam output dikekalkan); 'keepExisting' — tidak melakukan apa-apa dan mengekalkan dokumen sedia ada; 'fail' — menghasilkan ralat; atau saluran paip tersuai untuk logik kemas kini yang kompleks.
// whenMatched: 'merge' - only update changed fields, keep others
db.orders.aggregate([
{ $project: { userId: 1, orderCount: { $literal: 1 } } },
{ $merge: {
into: 'user_order_counts',
on: 'userId',
whenMatched: [{ $set: { orderCount: { $add: ['$orderCount', '$$new.orderCount'] } } }],
whenNotMatched: 'insert'
}}
]);
// Custom pipeline in whenMatched adds to existing count instead of replacingPilihan $merge whenNotMatched
Pilihan whenNotMatched mengawal perkara yang berlaku apabila dokumen output saluran paip tidak mempunyai padanan dalam koleksi sasaran. Pilihannya ialah: 'insert' — menambah dokumen baharu ke sasaran; 'discard' — mengabaikannya (tidak memasukkannya); atau 'fail' — menghasilkan ralat. Gabungan yang paling biasa ialah whenMatched: 'replace', whenNotMatched: 'insert', yang melaksanakan upsert penuh.
// Full upsert: replace existing, insert new
{ $merge: {
into: 'product_stats',
on: '_id',
whenMatched: 'replace',
whenNotMatched: 'insert'
}}
// Update only existing, silently skip new
{ $merge: {
into: 'product_stats',
on: '_id',
whenMatched: 'replace',
whenNotMatched: 'discard' // only update existing products
}}Paparan Terwujud Berperingkat Dengan $merge
Salah satu corak paling berkuasa yang didayakan oleh $merge ialah paparan terwujud berperingkat: bukannya mengira semula keseluruhan ringkasan setiap kali, anda menjalankan saluran paip hanya pada data baharu (menggunakan $match pada cap masa terkini) dan menggabungkan hasil berperingkat itu ke dalam koleksi ringkasan. Ini menjadikan penyegaran jauh lebih pantas bagi set data yang besar.
// Incremental update: only process last hour of orders
const oneHourAgo = new Date(Date.now() - 3600000);
db.orders.aggregate([
{ $match: { createdAt: { $gte: oneHourAgo } } }, // only NEW data
{ $group: {
_id: '$productId',
recentRevenue: { $sum: '$amount' },
recentOrders: { $sum: 1 }
}},
{ $merge: {
into: 'product_revenue',
on: '_id',
whenMatched: [
{ $set: {
totalRevenue: { $add: ['$totalRevenue', '$$new.recentRevenue'] },
totalOrders: { $add: ['$totalOrders', '$$new.recentOrders'] }
}}
],
whenNotMatched: 'insert'
}}
]);$out berbanding $merge: Bila Perlu Menggunakan Setiap Satu
Gunakan $out apabila anda mahukan penggantian gambaran penuh: sasaran hendaklah sentiasa menjadi hasil lengkap dan terkini daripada saluran paip—tiada kemas kini separa dan tiada sejarah yang dikekalkan. Sesuai untuk laporan kelompok malam yang menggantikan data semalam. Gunakan $merge apabila anda mahu mengemas kini secara berperingkat, menambah data atau melakukan upsert ke dalam koleksi sedia ada tanpa kehilangan data yang tidak dikira semula dalam larian ini. Sesuai untuk pengagregatan masa nyata atau hampir masa nyata yang dijalankan setiap jam.
// $out: nightly full replace
// Run at midnight: compute full summary, atomically replace target
{ $out: 'monthly_report' }
// $merge: hourly incremental update
// Run every hour: compute last hour's delta, merge into running total
{ $merge: {
into: 'running_totals',
on: '_id',
whenMatched: 'merge',
whenNotMatched: 'insert'
}}Keizinan dan Indeks pada Sasaran $out/$merge
Apabila $out mencipta semula koleksi, ia menggugurkan semua indeks pada sasaran (kecuali indeks _id). Anda mesti mencipta semula sebarang indeks sekunder selepas larian $out. $merge mengekalkan indeks sedia ada pada koleksi sasaran. Ini ialah satu lagi sebab untuk memilih $merge bagi koleksi yang kerap disegarkan—indeks anda tidak hilang pada setiap larian.
// After $out, recreate indexes on the refreshed collection
db.orders.aggregate([...stages, { $out: 'order_summary' }]);
// Now recreate needed indexes:
db.order_summary.createIndex({ userId: 1 });
db.order_summary.createIndex({ createdAt: -1 });
// $merge preserves existing indexes automatically
// No index recreation needed after $mergeSaluran Paip ETL Dengan $merge
$merge membolehkan saluran paip ETL asli MongoDB (Extract-Transform-Load): mengekstrak data daripada koleksi sumber, mengubahnya melalui peringkat pengagregatan dan memuatkan hasilnya ke dalam koleksi destinasi. Ini mengelakkan keperluan menggunakan alat ETL luaran untuk tugas pemindahan data biasa dalam kelompok MongoDB yang sama.
// ETL: clean and transform raw events into a processed_events collection
db.raw_events.aggregate([
// Extract: filter valid events
{ $match: { eventType: { $in: ['click', 'view', 'purchase'] }, userId: { $exists: true } } },
// Transform: reshape and enrich
{ $addFields: {
processedAt: '$$NOW',
eventDate: { $dateToString: { format: '%Y-%m-%d', date: '$timestamp' } }
}},
{ $project: { _id: 0, eventType: 1, userId: 1, eventDate: 1, processedAt: 1 } },
// Load: upsert into destination
{ $merge: {
into: 'processed_events',
on: ['userId', 'eventDate', 'eventType'],
whenMatched: 'keepExisting', // don't reprocess
whenNotMatched: 'insert'
}}
]);Semakan Pantas
Uji pemahaman anda tentang peringkat saluran paip $out dan $merge.
Rumusan Pelajaran
Dalam pelajaran ini, anda mempelajari bahawa: $out menggantikan koleksi sasaran secara atomik tetapi menggugurkan indeks sekunder, $merge melakukan upsert dokumen dengan tingkah laku whenMatched dan whenNotMatched yang boleh dikonfigurasikan, dan paparan terwujud berperingkat dengan $merge membolehkan penyegaran separa yang cekap. Kursus Peringkat Pengagregatan Lanjutan ini telah selesai—seterusnya kita akan meneroka pengumpul pengagregatan dengan lebih mendalam.
Pelajari JavaScript dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 30
- Pelajaran
- 120
Soalan Lazim
Adakah pelajaran “$out dan $merge: Menulis Hasil Saluran Paip” percuma?
Ya — teks penuh “$out dan $merge: Menulis Hasil Saluran Paip” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus MongoDB Academy, tingkat taraf kepada CoddyKit PRO. Kursus MongoDB Academy merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “$out dan $merge: Menulis Hasil Saluran Paip”?
Pelajar akan menghalakan output agregasi ke dalam koleksi baharu atau sedia ada menggunakan $out dan $merge untuk ETL serta paparan terwujud. Anda berlatih MongoDB Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan MongoDB Academy?
Tiada pengalaman terdahulu diperlukan. Pembelajaran MongoDB Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.
Berapa lamakah pelajaran “$out dan $merge: Menulis Hasil Saluran Paip” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran MongoDB Academy ini?
Ya. Setiap pelajaran MongoDB Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- $lookup: Menggabungkan Koleksi dalam Saluran Paip
- $unwind: Menguraikan Medan Tatasusunan
- $addFields, $replaceRoot dan $mergeObjects
- $out dan $merge: Menulis Hasil Saluran Paip