Node.js MongoDB Update

In a real-world application, data is rarely static. Whether a user is changing their profile picture, a product's stock levels are fluctuating, or a blog post's "view count" is increasing, you need a reliable way to modify existing records. Using Node.js with the official MongoDB driver, you can perform these modifications efficiently using targeted update operations.

 

Key Features of MongoDB Update

MongoDB doesn't just "overwrite" data; it provides a suite of atomic operators that allow for granular changes. This ensures that if two users update a document at the exact same time, the database handles the changes safely.

  1. Update One: Finds the first document matching your filter and applies the changes. This is most commonly used when updating specific records by a unique ID.
  2. Update Many: Applies changes to every single document that meets your criteria. This is perfect for "bulk" actions, such as marking all notifications as read.
  3. Flexible Operators: Instead of sending the whole document back, you use operators like $set (to change a value), $unset (to delete a field), and $inc (to perform math on a number).
Developer Tip: Update operations in MongoDB are atomic at the single-document level. This means you don't have to worry about a document being "half-updated" if a crash occurs during the process.

 

Step 1 Prerequisites

Before you begin, ensure you have a local MongoDB instance running or an Atlas connection string. You will also need the mongodb driver installed in your Node.js project directory.

npm install mongodb

Step 2 Update One Document

The updateOne() method is the surgical tool of MongoDB. It requires two main arguments: a query to find the document and an update document containing the changes you want to apply.

Common Mistake: Forgetting the $set operator. If you pass { name: 'Alice' } as the update argument, some drivers might interpret this as a replacement, potentially wiping out other fields in that document. Always use $set to modify specific fields.

Example Code

const { MongoClient } = require('mongodb');

// Connection URL and Database Name
const url = 'mongodb://127.0.0.1:27017';
const dbName = 'mydatabase';

async function updateOneDocument() {
  const client = new MongoClient(url);

  try {
    await client.connect();
    const db = client.db(dbName);
    const collection = db.collection('users');

    // Update the first document where age is 25
    // We use $set so that other fields (like 'email') remain untouched
    const result = await collection.updateOne(
      { age: 25 },
      { $set: { name: 'Alice Updated' } }
    );
    
    if (result.matchedCount === 0) {
      console.log("No document matched the query.");
    } else {
      console.log(`${result.modifiedCount} document(s) updated successfully`);
    }
  } finally {
    await client.close();
  }
}

updateOneDocument().catch(console.error);

Output:

1 document(s) updated

Step 3 Update Multiple Documents

If you need to perform a mass update—for example, giving every user in a specific category a "Premium" status—use updateMany(). It works identically to updateOne() but continues searching the entire collection until every matching document is modified.

Watch Out: Running updateMany on a massive collection (millions of rows) without an index on the query field can cause significant database lag. Always ensure your "filter" fields are indexed.

Example Code

async function updateMultipleDocuments() {
  const client = new MongoClient(url);

  try {
    await client.connect();
    const db = client.db(dbName);
    const collection = db.collection('users');

    // Real-world scenario: Activate all users over a certain age
    const result = await collection.updateMany(
      { age: { $gt: 25 } },
      { $set: { status: 'Active' } }
    );
    
    console.log(`Matched ${result.matchedCount} and updated ${result.modifiedCount} documents.`);
  } finally {
    await client.close();
  }
}

updateMultipleDocuments().catch(console.error);

Output:

2 document(s) updated

Step 4 Increment Field Value

One of the most powerful operators is $inc. Instead of fetching a number, adding to it in JavaScript, and saving it back (which can lead to "race conditions"), $inc tells MongoDB to perform the addition directly on the server.

Best Practice: Use $inc for counters like "likes," "page views," or "inventory stock." It is faster and prevents data loss that occurs when two users try to update the same counter simultaneously.

Example Code

async function incrementField() {
  const client = new MongoClient(url);

  try {
    await client.connect();
    const db = client.db(dbName);
    const collection = db.collection('users');

    // Increment age by 1. To decrement, use a negative number like -1.
    const result = await collection.updateMany(
      { name: 'Alice' },
      { $inc: { age: 1 } }
    );
    console.log(`${result.modifiedCount} document(s) updated`);
  } finally {
    await client.close();
  }
}

incrementField().catch(console.error);

Output:

1 document(s) updated

Step 5 Unset a Field

Sometimes you don't want to change a value; you want to remove the field entirely from a document. This is common during database schema migrations where a field is no longer needed.

Example Code

async function unsetField() {
  const client = new MongoClient(url);

  try {
    await client.connect();
    const db = client.db(dbName);
    const collection = db.collection('users');

    // The value passed to $unset (empty string here) doesn't matter; 
    // the field will be removed regardless.
    const result = await collection.updateMany(
      { age: { $gt: 25 } },
      { $unset: { status: "" } }
    );
    console.log(`Field removed from ${result.modifiedCount} document(s)`);
  } finally {
    await client.close();
  }
}

unsetField().catch(console.error);

Output:

2 document(s) updated

Step 6 Replace a Document

replaceOne() is different from updateOne(). While updateOne() modifies specific fields, replaceOne() drops the entire document and replaces it with the new object you provide, though the _id remains the same. This is useful when you want to completely "reset" a record.

Watch Out: Any fields present in the old document that are NOT in the new replacement document will be lost forever.

Example Code

async function replaceDocument() {
  const client = new MongoClient(url);

  try {
    await client.connect();
    const db = client.db(dbName);
    const collection = db.collection('users');

    // This will replace the entire Alice document with these three fields only.
    const result = await collection.replaceOne(
      { name: 'Alice Updated' },
      { name: 'Alice Replaced', age: 30, status: 'Replaced' }
    );
    console.log(`${result.modifiedCount} document(s) replaced`);
  } finally {
    await client.close();
  }
}

replaceDocument().catch(console.error);

Output:

1 document(s) replaced

 

Summary

Mastering updates is key to building dynamic Node.js applications. By using updateOne for specific changes and updateMany for bulk edits, you gain full control over your data. Remember to use operators like $set and $inc to keep your updates efficient and safe. As a next step, consider looking into upserts—an option that creates a document if one doesn't already exist during an update.