MongoDB Academy · पाठ

$out और $merge: डेटा-प्रवाह परिणाम लिखना

शिक्षार्थी ETL और भौतिकीकृत दृश्यों के लिए $out और $merge का उपयोग करके एग्रीगेशन आउटपुट को नए या मौजूदा संग्रह में भेजेंगे।

पाठ 4, कुल 4 में से13 चरण

$out और $merge: डेटा-प्रवाह परिणाम लिखना, CoddyKit पर MongoDB Academy का एक निःशुल्क पाठ है। यह 4 में से 4वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह MongoDB Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। MongoDB Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

Pipeline के परिणाम collections में लिखना

डिफ़ॉल्ट रूप से aggregation pipeline के परिणाम cursor के रूप में client को लौटाए जाते हैं। कभी-कभी आप परिणामों को बाद में materialised view, reporting cache या ETL target के रूप में उपयोग करने के लिए MongoDB collection में स्थायी रूप से सहेजना चाहते हैं। MongoDB इसके लिए दो चरण प्रदान करता है: $out, जो target collection को atomic रूप से बदल देता है, और $merge, जो परिणामों को मौजूदा collection में upsert या merge करता है।

$out चरण

$out एक परमाणु ऑपरेशन में पाइपलाइन के सभी आउटपुट दस्तावेज़ों को नए या मौजूदा संग्रह में लिखता है। यदि लक्ष्य संग्रह मौजूद है, तो $out उसे नए परिणामों से पूरी तरह बदल देता है—पुराना संग्रह हटा दिया जाता है और नया संग्रह परमाणु रूप से उसका स्थान ले लेता है। यदि वह मौजूद नहीं है, तो MongoDB उसे बना देता है। पाइपलाइन में $out अंतिम चरण होना चाहिए और यह क्लाइंट को कुछ भी वापस नहीं करता।

// 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
]);

$out की परमाणुता की गारंटी

$out परमाणु प्रतिस्थापन प्रदान करता है: यह पहले सभी परिणामों को एक अस्थायी संग्रह में लिखता है, फिर एक ही परमाणु ऑपरेशन में अस्थायी संग्रह का नाम बदलकर लक्ष्य नाम कर देता है। इसका अर्थ है कि लक्ष्य संग्रह को पढ़ने वाले लोगों को हमेशा या तो पुराना पूरा डेटा दिखाई देगा या नया पूरा डेटा—कभी भी अधूरा परिणाम नहीं। इसलिए $out किसी रिपोर्टिंग संग्रह को रोज़ाना ताज़ा करने के लिए प्रोडक्शन में सुरक्षित है।

// 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 से अलग डेटाबेस में लिखना

MongoDB 4.4 से $out ऑब्जेक्ट सिंटैक्स का समर्थन करता है, जिससे आप किसी अलग डेटाबेस के संग्रह में लिख सकते हैं। ऑब्जेक्ट रूप में db (डेटाबेस का नाम) और coll (संग्रह का नाम), दोनों निर्दिष्ट करें। यह एक ही क्लस्टर में परिचालन और रिपोर्टिंग डेटाबेस को अलग रखने के लिए उपयोगी है।

// 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_revenue

$merge चरण

MongoDB 4.2 में प्रस्तुत किया गया $merge, $out से अधिक लचीला है: लक्ष्य संग्रह को बदलने के बजाय, यह प्रत्येक आउटपुट दस्तावेज़ को लक्ष्य में अपसर्ट करता है। आप मर्ज कुंजी निर्धारित करते हैं, यानी कौन-से फ़ील्ड मौजूदा दस्तावेज़ों की पहचान करते हैं, और प्रत्येक आउटपुट दस्तावेज़ के लिए MongoDB तय करता है कि उसे सम्मिलित करना है, मौजूदा दस्तावेज़ को अपडेट करना है, उसे बदलना है, विफल होना है या मौजूदा दस्तावेज़ को बनाए रखना है।

// 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
    }
  }
]);

$merge के whenMatched विकल्प

whenMatched विकल्प यह नियंत्रित करता है कि पाइपलाइन का आउटपुट दस्तावेज़ लक्ष्य संग्रह में किसी मौजूदा दस्तावेज़ से मेल खाने पर क्या होगा। विकल्प हैं: 'replace' — मौजूदा दस्तावेज़ को अधिलेखित करें; 'merge' — फ़ील्ड मर्ज करें (आउटपुट में न होने वाले मौजूदा फ़ील्ड बनाए रखें); 'keepExisting' — कुछ न करें और मौजूदा दस्तावेज़ सुरक्षित रखें; 'fail' — त्रुटि उत्पन्न करें; या जटिल अपडेट तर्क के लिए एक कस्टम पाइपलाइन।

// 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 replacing

$merge के whenNotMatched विकल्प

whenNotMatched विकल्प यह नियंत्रित करता है कि पाइपलाइन के आउटपुट दस्तावेज़ का लक्ष्य संग्रह में कोई मिलान न मिलने पर क्या होगा। विकल्प हैं: 'insert' — नया दस्तावेज़ लक्ष्य में जोड़ें; 'discard' — उसे अनदेखा करें (सम्मिलित न करें); या 'fail' — त्रुटि उत्पन्न करें। सबसे सामान्य संयोजन whenMatched: 'replace', whenNotMatched: 'insert' है, जो पूर्ण अपसर्ट लागू करता है।

// 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
}}

$merge के साथ वृद्धिशील भौतिकीकृत दृश्य

$merge से संभव होने वाले सबसे शक्तिशाली पैटर्न में से एक है वृद्धिशील भौतिकीकृत दृश्य: हर बार पूरे सारांश की पुनर्गणना करने के बजाय, आप पाइपलाइन को केवल नए डेटा पर चलाते हैं (हाल के टाइमस्टैम्प पर $match का उपयोग करके) और वृद्धिशील परिणामों को सारांश संग्रह में मर्ज करते हैं। इससे बड़े डेटासेट के लिए ताज़ा करना बहुत तेज़ हो जाता है।

// 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 बनाम $merge: किसका उपयोग कब करें

जब आपको पूरे स्नैपशॉट का प्रतिस्थापन चाहिए, तब $out का उपयोग करें: लक्ष्य हमेशा पाइपलाइन का पूरा, नया परिणाम होना चाहिए—न आंशिक अपडेट और न ही पुराना इतिहास। यह उन रात्रिकालीन बैच रिपोर्टों के लिए अच्छा है जो कल के डेटा को बदल देती हैं। जब आप किसी मौजूदा संग्रह को क्रमिक रूप से अपडेट करना, उसमें जोड़ना या अपसर्ट करना चाहते हों और इस बार दोबारा गणना न किए गए डेटा को खोना न चाहते हों, तब $merge का उपयोग करें। यह हर घंटे चलने वाले रीयल-टाइम या लगभग रीयल-टाइम एग्रीगेशन के लिए अच्छा है।

// $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'
}}

$out/$merge लक्ष्यों पर अनुमतियाँ और इंडेक्स

जब $out किसी संग्रह को फिर से बनाता है, तो वह लक्ष्य पर मौजूद सभी इंडेक्स हटा देता है (_id इंडेक्स को छोड़कर)। $out के चलने के बाद आपको सभी सेकेंडरी इंडेक्स फिर से बनाने होंगे। $merge लक्ष्य संग्रह के मौजूदा इंडेक्स सुरक्षित रखता है। बार-बार ताज़ा किए जाने वाले संग्रहों के लिए $merge को प्राथमिकता देने का यह एक और कारण है—हर बार चलाने पर आपके इंडेक्स नष्ट नहीं होते।

// 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 $merge

$merge के साथ ETL पाइपलाइनें

$merge MongoDB-native ETL (Extract-Transform-Load) पाइपलाइनें सक्षम करता है: स्रोत संग्रह से डेटा निकालें, एग्रीगेशन चरणों के माध्यम से उसे रूपांतरित करें और परिणामों को गंतव्य संग्रह में लोड करें। इससे एक ही MongoDB क्लस्टर के भीतर सामान्य डेटा स्थानांतरण कार्यों के लिए बाहरी ETL टूल की आवश्यकता नहीं रहती।

// 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'
  }}
]);

त्वरित जाँच

$out और $merge पाइपलाइन चरणों की अपनी समझ जाँचें।

पाठ का पुनरावलोकन

इस पाठ में आपने सीखा: $out लक्ष्य संग्रह को परमाणु रूप से बदल देता है, लेकिन सेकेंडरी इंडेक्स हटा देता है; $merge दस्तावेज़ों को अपसर्ट करता है, जिसमें whenMatched और whenNotMatched का व्यवहार कॉन्फ़िगर किया जा सकता है; और $merge के साथ वृद्धिशील भौतिकीकृत दृश्य कुशल आंशिक ताज़ाकरण संभव बनाते हैं। इससे Advanced Aggregation Stages पाठ्यक्रम पूरा होता है—अब हम एग्रीगेशन संचायकों का विस्तार से अध्ययन करेंगे।

शुरुआत निःशुल्क

एआई शिक्षक के साथ JavaScript सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
30
पाठ
120

अक्सर पूछे जाने वाले प्रश्न

क्या “$out और $merge: डेटा-प्रवाह परिणाम लिखना” पाठ निःशुल्क है?

हाँ—“$out और $merge: डेटा-प्रवाह परिणाम लिखना” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और MongoDB Academy पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। MongoDB Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“$out और $merge: डेटा-प्रवाह परिणाम लिखना” में मैं क्या सीखूँगा?

शिक्षार्थी ETL और भौतिकीकृत दृश्यों के लिए $out और $merge का उपयोग करके एग्रीगेशन आउटपुट को नए या मौजूदा संग्रह में भेजेंगे। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ MongoDB Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या MongoDB Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर MongoDB Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 4वाँ पाठ है।

“$out और $merge: डेटा-प्रवाह परिणाम लिखना” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस MongoDB Academy पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर MongoDB Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. $lookup: डेटा-प्रवाह में संग्रहों को जोड़ना
  2. $unwind: ऐरे फ़ील्ड को अलग करना
  3. $addFields, $replaceRoot और $mergeObjects
  4. $out और $merge: डेटा-प्रवाह परिणाम लिखना
← MongoDB Academy पर वापस जाएँ