Updating Array Fields and Array Elements

MongoDB provides update operators for adding, removing, and modifying array elements.

$push

$push appends a value to an array.

db.users.updateOne(
  { name: "Arun" },
  { $push: { skills: "MongoDB" } }
);

If the array does not exist, $push creates it. If the field exists but is not an array, the update fails.

$addToSet

$addToSet adds a value only if an equal value is not already present.

db.users.updateOne(
  { name: "Arun" },
  { $addToSet: { skills: "MongoDB" } }
);

For arrays of embedded documents, equality is based on document value comparison, including field order. $addToSet does not enforce uniqueness by a selected nested key such as skillId.

$each

$each adds multiple values with operators such as $push and $addToSet.

db.users.updateOne(
  { name: "Arun" },
  {
    $addToSet: {
      skills: {
        $each: ["React", "Node.js", "MongoDB"]
      }
    }
  }
);

$pull

$pull removes all array elements that match the supplied condition.

db.users.updateOne(
  { name: "Arun" },
  { $pull: { skills: "LegacySkill" } }
);

For an array of embedded documents, you can match by nested field values.

$pop

$pop removes one element from either end of an array.

// Remove the last element.
db.users.updateOne(
  { name: "Arun" },
  { $pop: { skills: 1 } }
);

// Remove the first element.
db.users.updateOne(
  { name: "Arun" },
  { $pop: { skills: -1 } }
);

$pullAll

$pullAll removes all array elements equal to any of the specified values.

db.users.updateOne(
  { name: "Arun" },
  { $pullAll: { skills: ["LegacySkill", "DeprecatedSkill"] } }
);

Positional update operator

The positional $ operator updates the first array element matched by the query condition in supported update patterns.

For example, when the query identifies a student and a matching score element, the positional operator can target that element.

db.students.updateOne(
  { _id: 1, "scores.subject": "Math" },
  { $set: { "scores.$.score": 95 } }
);

The positional operator has restrictions and should be used only when the query correctly identifies the intended array element.

Array filters

Array filters allow updates to selected elements using identifiers in the update path.

db.students.updateOne(
  { _id: 1 },
  { $set: { "scores.$[item].passed": true } },
  { arrayFilters: [{ "item.score": { $gte: 40 } }] }
);

This updates every matching array element in the selected document. The update path identifier and array filter identifier must correspond.

Positional all operator

The $[] operator targets all elements of an array.

db.students.updateOne(
  { _id: 1 },
  { $inc: { "scores.$[].attempts": 1 } }
);

This increments attempts for every element in the selected document's scores array, assuming the path and element structures are valid.

Manipulate array values
db.arrayUpdateDemo.insertOne({
  name: "Arun",
  skills: ["JavaScript", "React"],
  scores: [
    { subject: "Math", score: 35, passed: false },
    { subject: "Science", score: 55, passed: true }
  ]
});

// Add a unique skill.
db.arrayUpdateDemo.updateOne(
  { name: "Arun" },
  { $addToSet: { skills: "MongoDB" } }
);

// Add multiple unique skills.
db.arrayUpdateDemo.updateOne(
  { name: "Arun" },
  {
    $addToSet: {
      skills: { $each: ["Node.js", "MongoDB"] }
    }
  }
);

// Update the Math score.
db.arrayUpdateDemo.updateOne(
  { name: "Arun", "scores.subject": "Math" },
  { $set: { "scores.$.score": 45, "scores.$.passed": true } }
);

// Inspect the result.
db.arrayUpdateDemo.findOne({ name: "Arun" });
💡 The example demonstrates adding unique array values and updating the first matching embedded score element. Array updates should use filters that identify the intended document and array element.
Key Takeaways
  • $push appends values, while $addToSet avoids adding an equal existing value.
  • $pull removes matching array elements.
  • $pop removes one element from an end of an array.
  • The positional $ operator targets a matched array element.
  • Array filters can target selected elements using explicit identifiers.
Knowledge Check

Which update operator is designed to add a value only if an equal value is not already present in an array?