MongoDB $setField Operator

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 4 Examples
Object / Field

What You’ll Learn

The $setField operator returns a new object with a named field set to a value you specify. The field name can be dynamic — ideal for flexible schemas, metric maps, and fields with special characters.

01

Set Field

Add or update.

02

field + value

Dynamic names.

03

New Object

Returns copy.

04

Aggregation

$project / $addFields.

05

Use Cases

Metrics, config.

06

vs $getField

Write vs read.

Definition and Usage

In MongoDB’s aggregation framework, the $setField operator takes an object, sets one field to a new value, and returns the updated object. If the field already exists, its value is replaced. If it does not exist, the field is added. The original input object is not modified unless you assign the result back to a field.

This is the write counterpart to $getField. Use it when field names come from document data — like updating whichever metric key is stored in metricKey — or when field names contain dots or $ characters that dot notation cannot handle cleanly.

💡
Beginner Tip

$setField returns a new object. To persist the change, assign the result: metrics: { $setField: { ... } } inside $addFields or an update pipeline $set stage.

📝 Syntax

The $setField operator takes an object with field, input, and value:

mongosh
{
  $setField: {
    field: <string expression>,
    input: <object expression>,
    value: <expression>
  }
}

Common Patterns

mongosh
// Set a static field on nested object
{ field: "status", input: "$config", value: "active" }

// Set a dynamic field from document data
{ field: "$metricKey", input: "$metrics", value: 100 }

// Add field with special characters in name
{ field: "a.b", input: "$data", value: "ok" }

Syntax Rules

  • field — the name of the field to set (literal or expression).
  • input — the source object to copy and modify.
  • value — the new value for that field (any type).
  • Returns a new object with the field added or updated.
  • Returns null if input is null.
  • Use inside $project, $addFields, or $set (MongoDB 5.0+).

💡 $setField vs $getField vs dot notation

$getField — read a field value from an object
$setField — write a field value; returns updated object
Dot notation — fine for fixed paths like "config.status"
Dynamic names — use $setField when field: "$metricKey"

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation field-access expression operator
Syntax{ $setField: { field, input, value } }
OutputNew object with field set
Mutates input?No (returns a copy with change)
MongoDB version5.0+
Static field
{
  $setField: {
    field: "status",
    input: "$config",
    value: "active"
  }
}

Fixed name

Dynamic field
{
  field: "$metricKey",
  input: "$metrics",
  value: 100
}

Name from data

Assign back
metrics: {
  $setField: { ... }
}

Persist change

Null input
null

Returns null

Examples Gallery

Update nested config objects, set dynamic metric keys, handle special field names, and combine read-modify-write with $getField.

📚 Configuration Objects

Add or update a field on a nested config object.

Sample Input Documents

Suppose you have a apps collection:

mongosh
[
  {
    "_id": 1,
    "name": "Dashboard",
    "config": { "theme": "dark", "version": 2 },
    "metrics": { "views": 100, "clicks": 40 },
    "metricKey": "views"
  },
  {
    "_id": 2,
    "name": "API",
    "config": { "theme": "light" },
    "metrics": { "requests": 5000 },
    "metricKey": "requests"
  }
]

Example 1 — Set a Static Field on a Nested Object

Add status: "active" to each app’s config:

mongosh
db.apps.aggregate([
  {
    $project: {
      name: 1,
      config: {
        $setField: {
          field: "status",
          input: "$config",
          value: "active"
        }
      }
    }
  }
])

How It Works

$setField copies config, adds or updates status, and returns the new object. Existing fields like theme are preserved.

📈 Dynamic and Special Field Names

Update whichever metric key the document specifies, and set fields with dots in the name.

Example 2 — Set a Dynamic Metric Field

Increment the metric named in metricKey by setting it to a new value:

mongosh
db.apps.aggregate([
  {
    $project: {
      name: 1,
      metrics: {
        $setField: {
          field: "$metricKey",
          input: "$metrics",
          value: {
            $add: [
              {
                $getField: {
                  field: "$metricKey",
                  input: "$metrics"
                }
              },
              1
            ]
          }
        }
      }
    }
  }
])

// metricKey: "views" → metrics.views increases by 1

How It Works

$getField reads the current value; $setField writes it back under the dynamic key. This read-modify-write pattern is common for flexible metric maps.

Example 3 — Persist Change With $addFields

Overwrite config in the pipeline output with the updated object:

mongosh
db.apps.aggregate([
  {
    $addFields: {
      config: {
        $setField: {
          field: "lastChecked",
          input: "$config",
          value: "$$NOW"
        }
      }
    }
  }
])

How It Works

$addFields replaces config with the object returned by $setField. Use $merge or an update pipeline to write back to the collection.

Example 4 — Field Name With a Dot

Set a field whose name literally contains a dot (where dot notation fails):

mongosh
db.records.aggregate([
  {
    $project: {
      data: {
        $setField: {
          field: "user.name",
          input: "$data",
          value: "Alice"
        }
      }
    }
  }
])

// Creates field "user.name" (not nested user → name)

How It Works

$setField treats field as a single field name string. This is useful for legacy schemas or imported JSON with dotted keys.

Bonus — Update Pipeline With $set

Use aggregation syntax in an update to set a dynamic nested field:

mongosh
db.apps.updateOne(
  { _id: 1 },
  [
    {
      $set: {
        metrics: {
          $setField: {
            field: "views",
            input: "$metrics",
            value: 200
          }
        }
      }
    }
  ]
)

How It Works

Update pipelines (array form) support aggregation expressions. $setField builds the new metrics object server-side without client-side merge logic.

🚀 Use Cases

  • Dynamic schemas — update whichever key a document points to (metrics, preferences, flags).
  • Nested config — add or change fields on embedded configuration objects.
  • Special field names — set fields containing dots or $ prefixes.
  • Update pipelines — compute new nested objects during server-side updates.

🧠 How $setField Works

1

MongoDB evaluates field, input, and value

The field name, source object, and new value are resolved from literals or expressions.

Input
2

A copy of the object is created

MongoDB clones input and sets the named field to value (add or replace).

Copy
3

The updated object is returned

Assign the result to a field in $project, $addFields, or an update $set stage.

Output
=

Object with field set

All other fields from input remain unless overwritten.

Conclusion

The $setField operator dynamically sets a field on an object and returns the updated copy. It is the write-side partner to $getField, and it shines when field names are data-driven or contain special characters.

Remember: assign the returned object to persist changes. Next in the series: $setIntersection.

💡 Best Practices

✅ Do

  • Assign the returned object back to the field you want to update
  • Pair with $getField for read-modify-write on dynamic keys
  • Use for field names with dots or $ prefixes
  • Prefer dot notation when field paths are fixed and simple
  • Use update pipelines when persisting nested object changes

❌ Don’t

  • Assume input is mutated in place — it is not
  • Use $setField when a simple $set: { \"a.b\": v } suffices
  • Forget that null input returns null
  • Confuse literal field "user.name" with nested path user.name
  • Expect MongoDB versions before 5.0 to support $setField

Key Takeaways

Knowledge Unlocked

Five things to remember about $setField

Use these points when setting fields on objects in pipelines.

5
Core concepts
🔢 02

field + input + value

Three args.

Syntax
🛠 03

New object

Non-destructive.

Output
🔄 04

vs $getField

Write vs read.

Pair
05

Assign back

To persist.

Pattern

❓ Frequently Asked Questions

$setField returns a new object with a specified field set to a given value. If the field already exists, its value is replaced; if not, the field is added. The field name can be dynamic — stored in another field or computed at runtime.
The syntax is { $setField: { field: <string expression>, input: <object expression>, value: <expression> } }. The field argument is the name to set; input is the object to copy and modify; value is the new field value.
$getField reads a field value from an object. $setField writes a field value and returns the updated object. They are inverse operations for dynamic field access.
Use $setField when the field name is not fixed at pipeline design time, or when the name contains dots or starts with $. Dot notation like { $set: { "metrics.revenue": 100 } } only works for known, simple paths.
Use $setField inside aggregation expression stages such as $project, $addFields, and $set. It is also useful in update pipelines that use aggregation syntax (MongoDB 5.0+).

Continue the Operator Series

Move on to $setIntersection for shared array elements, or review $getField for reading dynamic fields.

Next: $setIntersection →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful