Mongoose: How to update values in an array of objects

Updated: December 31, 2023 By: Guest Contributor Post a comment

Mongoose ORM simplifies MongoDB interactions. This tutorial explores updating objects within a document’s array, highlighting the power and flexibility Mongoose offers with practical code examples.

Before we start writing code, ensure you have Node.js and MongoDB installed. Familiarity with Mongoose and basic JavaScript concepts like async/await is also needed.

Setting Up Mongoose

First, we set up Mongoose. Install it via npm and connect to your MongoDB database.

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database');

Defining The Schema

Define a schema that includes an array of objects, using a sample `Book` model with an array of `authors`.

const bookSchema = new mongoose.Schema({
  title: String,
  authors: [{ name: String, age: Number }]
});
const Book = mongoose.model('Book', bookSchema);

Basic Array Update

For a simple update, let’s use `findOneAndUpdate` along with the `$set` operator to modify an author’s name.

async function updateAuthor(bookId, authorId, newName) {
  const result = await Book.findOneAndUpdate(
    { _id: bookId, 'authors._id': authorId },
    { '$set': { 'authors.$.name': newName } },
    { new: true }
  );
  return result;
}

Adding to the Array

To add a new author, use `$push`:

async function addAuthor(bookId, author) {
  const result = await Book.findByIdAndUpdate(
    bookId,
    { '$push': { authors: author } },
    { new: true }
  );
  return result;
}

Removing from the Array

Use `$pull` to remove an author given a specific condition:

async function removeAuthor(bookId, authorName) {
  const result = await Book.findByIdAndUpdate(
    bookId,
    { '$pull': { authors: { name: authorName } } },
    { new: true }
  );
  return result;
}

Advanced Update Patterns

For complex updates, like incrementing age of all authors, combine `$inc` with the `$[]` all positional operator.

async function incrementAuthorsAge(bookId) {
  const result = await Book.updateOne(
    { _id: bookId },
    { '$inc': { 'authors.$[].age': 1 } }
  );
  return result;
}

Updating Multiple Array Items

When updating multiple items based on a condition, use the filtered positional operator.

async function updateMultipleAuthors(bookId, ageThreshold, newName) {
  const result = await Book.updateOne(
    { _id: bookId },
    { '$set': { 'authors.$[elem].name': newName } },
    { arrayFilters: [{ 'elem.age': { '$gte': ageThreshold } }] }
  );
  return result;
}

Conclusion

This tutorial covered updating array elements in Mongoose, showcasing flexibility from simple to complex scenarios, solidifying your backend development skills with MongoDB.