0Pricing
MongoDB Academy · Ders

$addFields, $replaceRoot ve $mergeObjects

Öğrenenler, hesaplanan alanlar ekleyecek, iç içe alt belgeleri kök düzeye taşıyacak ve işlem hattı içinde nesneleri birleştireceklerdir.

$addFields, $replaceRoot ve $mergeObjects, CoddyKit'te ücretsiz bir MongoDB Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, MongoDB Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. MongoDB Academy kursu toplamda 4 dersten oluşur.

Bu dersin bazı bölümleri henüz çevrilmemiş olup İngilizce olarak gösterilmektedir.

Three Reshaping Stages

While $project is the primary document-reshaping tool, three additional stages offer more targeted transformations: $addFields adds new fields while preserving all existing ones, $replaceRoot promotes a sub-document to become the new root document, and $mergeObjects merges multiple objects into one. Together they cover reshaping patterns that would be verbose or impossible with $project alone.

$addFields: Adding Without Dropping

$addFields (also available as its alias $set) passes through all existing document fields and adds or overwrites only the specified fields. This is the key difference from $project in inclusion mode, where you must explicitly list every field you want to keep. Use $addFields whenever you want to enrich a document with computed fields without listing every existing field.

// $addFields preserves all existing fields
db.products.aggregate([{
  $addFields: {
    // Add computed fields; all original fields (name, price, etc.) are kept
    totalWithTax: { $multiply: ['$price', 1.1] },
    priceLabel: { $concat: ['$', { $toString: '$price' }] },
    isExpensive: { $gt: ['$price', 1000] }
  }
}]);
// All original product fields PLUS the three new computed fields

$set: The Modern Alias for $addFields

MongoDB 4.2 introduced $set as an alias for $addFields in both aggregation pipelines and update operations. The two are completely interchangeable in pipeline context. $set is the preferred modern spelling because it is more intuitive and mirrors the $set update operator used in updateOne(). Use whichever you find more readable.

// $set (modern) and $addFields (classic) are identical
db.orders.aggregate([{
  $set: {  // same as $addFields
    totalWithShipping: { $add: ['$amount', '$shippingFee'] },
    daysToDeliver: {
      $divide: [
        { $subtract: ['$deliveredAt', '$createdAt'] },
        1000 * 60 * 60 * 24
      ]
    }
  }
}]);

Overwriting Existing Fields With $addFields

When you specify a field name that already exists in the document, $addFields overwrites the existing value with the new computed value. This is useful for normalising data—for example, converting a string field to lowercase in the pipeline output without modifying the stored document.

// Normalise email to lowercase in pipeline output
db.users.aggregate([{
  $addFields: {
    email: { $toLower: '$email' }  // overwrites existing email field
  }
}]);
// The stored document is unchanged; only the pipeline output is normalised

// Promote a nested field to the top level by overwriting
db.orders.aggregate([{
  $addFields: {
    city: '$shippingAddress.city'  // copy nested field to top level
  }
}]);

$replaceRoot: Making a Sub-Document the Root

$replaceRoot replaces the entire root document with a specified sub-document or expression. The new root must be an object. This is useful after a $lookup + $unwind when you want the joined document to be the primary shape, or when you want to surface a nested sub-document as the output document while discarding the parent fields.

// Document: { order: { id: 1, amount: 100, customer: { name: 'Alice' } } }

// Make the nested 'order' sub-document the new root
db.transactions.aggregate([{
  $replaceRoot: { newRoot: '$order' }
}]);
// Output: { id: 1, amount: 100, customer: { name: 'Alice' } }
// The outer 'order' wrapper is gone; order's fields are now at the root level

$replaceWith: Alias for $replaceRoot

MongoDB 4.2 introduced $replaceWith as a more concise alias for $replaceRoot. Instead of { $replaceRoot: { newRoot: expr } }, you can write { $replaceWith: expr }. The two are completely equivalent. $replaceWith is often used after $lookup/$unwind to surface the joined document as the primary result.

// After lookup + unwind, make the joined product the root
db.orders.aggregate([
  { $lookup: { from: 'products', localField: 'productId', foreignField: '_id', as: 'product' } },
  { $unwind: '$product' },
  // Promote product to root, but keep orderId
  { $replaceWith: {
    $mergeObjects: ['$product', { orderId: '$_id', orderAmount: '$amount' }]
  }}
]);

$mergeObjects: Combining Two Objects

$mergeObjects merges multiple objects into a single object. When two objects have the same field, the last one wins. It is commonly used inside $replaceWith or $addFields to flatten a joined document and add extra fields at the same time. $mergeObjects can accept an array of objects or be used as a $group accumulator.

// Merge two objects - last key wins on conflict
db.users.aggregate([{
  $replaceWith: {
    $mergeObjects: [
      { defaultRole: 'viewer', isActive: false },  // defaults first
      '$$ROOT',                                     // actual doc overrides defaults
      { processedAt: '$$NOW' }                      // add computed field last
    ]
  }
}]);

$mergeObjects as a $group Accumulator

When used as a $group accumulator, $mergeObjects merges all documents in a group into a single object. This is useful for combining multiple partial documents that together form a complete record—for example, gathering all update events for an entity and merging them into a single 'current state' document.

// Merge all update events per entity into one current state
db.events.aggregate([
  { $sort: { timestamp: 1 } },  // process oldest first
  { $group: {
    _id: '$entityId',
    // Merge all event deltas into one object; later events override earlier
    currentState: { $mergeObjects: '$delta' }
  }}
]);
// Each group's 'delta' objects are merged sequentially, last wins

Practical Pattern: Flatten $lookup Result

A very common pattern is to use $replaceWith + $mergeObjects to flatten a looked-up document into the parent document's root, adding the parent's relevant fields alongside the joined document's fields. This produces a clean, flat output object that's easy to serialise and send to the client.

// Flatten order + product into a single output document
db.orders.aggregate([
  { $lookup: {
    from: 'products',
    localField: 'productId',
    foreignField: '_id',
    as: 'product'
  }},
  { $unwind: '$product' },
  { $replaceWith: {
    $mergeObjects: [
      '$product',                            // all product fields at root
      { orderId: '$_id', qty: '$qty', total: { $multiply: ['$product.price', '$qty'] } }
    ]
  }}
]);
// Clean flat output: { name, category, price, orderId, qty, total }

$unset: Removing Fields

$unset (available since MongoDB 4.2) removes specific fields from documents in the pipeline. It's the inverse of $addFields: while $addFields adds fields without touching others, $unset removes specified fields while passing through everything else. This is cleaner than using $project with all fields set to 1 just to exclude one field.

// Remove sensitive fields from output
db.users.aggregate([{
  $unset: ['password', 'apiKey', '__v']  // array of field names to remove
}]);
// All fields except password, apiKey, and __v are passed through

// Remove a single field
db.orders.aggregate([{ $unset: 'internalNotes' }]);

// Remove nested field with dot notation
db.users.aggregate([{ $unset: 'profile.ssn' }]);

Combining $addFields, $replaceRoot, and $mergeObjects

These three stages work together in sophisticated reshaping pipelines. A typical sequence is: use $addFields to compute derived fields, use $lookup to join related data, use $unwind to flatten the join, then use $replaceWith + $mergeObjects to produce a clean output shape. This combination covers most API response shaping needs without application-side transformation.

db.invoices.aggregate([
  { $addFields: { taxAmount: { $multiply: ['$subtotal', 0.08] } } },
  { $lookup: { from: 'clients', localField: 'clientId', foreignField: '_id', as: 'client' } },
  { $unwind: '$client' },
  { $replaceWith: {
    $mergeObjects: [
      { invoiceId: '$_id', subtotal: '$subtotal', taxAmount: '$taxAmount' },
      { clientName: '$client.name', clientEmail: '$client.email' }
    ]
  }},
  { $unset: ['_id'] }
]);

Quick Check

Test your understanding of $addFields, $replaceRoot, and $mergeObjects.

Lesson Recap

In this lesson you learned: $addFields/$set adds fields while preserving all existing ones, $replaceRoot/$replaceWith promotes a sub-document to the root, and $mergeObjects combines multiple objects with last-key-wins semantics. Next up we explore $out and $merge for writing pipeline results to collections.

Sıkça Sorulan Sorular

“$addFields, $replaceRoot ve $mergeObjects” dersi ücretsiz mi?

Evet — “$addFields, $replaceRoot ve $mergeObjects” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve MongoDB Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. MongoDB Academy kursu toplamda 4 dersten oluşur.

“$addFields, $replaceRoot ve $mergeObjects” dersinde ne öğreneceğim?

Öğrenenler, hesaplanan alanlar ekleyecek, iç içe alt belgeleri kök düzeye taşıyacak ve işlem hattı içinde nesneleri birleştireceklerdir. MongoDB Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

MongoDB Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te MongoDB Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.

“$addFields, $replaceRoot ve $mergeObjects” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu MongoDB Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her MongoDB Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. $lookup: İşlem Hattında Koleksiyonları Birleştirme
  2. $unwind: Dizi Alanlarını Ayrıştırma
  3. $addFields, $replaceRoot ve $mergeObjects
  4. $out ve $merge: İşlem Hattı Sonuçlarını Yazma
← MongoDB Academy Sayfasına Dön