Inserting & Updating Documents

4.A Hundred New Products by Morning

M

In this chapter

We'll meet MongoDB's batch write operations for real — insertMany, updateMany, $inc/$unset/$push, and upsert — through a real flash-sale, all-at-once onboarding.

9–11 min

The Problem in Real Life

Circuit & Co. calls at midnight: forty new products, ready to list before the flash sale opens at 6 a.m. And every electronics listing already on the catalog needs a sale tag and a bumped view counter for the sale banner — by morning, not one document at a time.

Sarah has written insertOne() and updateOne() a hundred times by now. Tonight, once each, isn't going to work.

S

One document at a time was fine yesterday. It won't be fine tonight.

Sarah

One Document at a Time vs. Everything at Once

insertMany — every document in one call

An array of documents, saved in a single call, each one still shaped for what it actually is.

updateMany — the same change, everywhere it matches

One filter, one update, applied to every matching document at once instead of one at a time.

Atomic, single-document updates

$set, $inc, $unset, and $push each change exactly what they target — another reader never sees a half-applied write.

Upsert — one call, either outcome

Update if it exists, insert if it doesn't — no separate existence check needed first.

Inserting & Updating Documents

insertOne() and updateOne() both have a plural counterpart built for exactly this — the same operation, applied to many documents in a single call, instead of one round trip per document.

insertMany() takes an array of documents and saves every one of them in a single call — each document still shaped however that specific product needs, exactly like insertOne(), just forty of them instead of one.

insertMany — Every New Product in One Call
db.listings.insertMany([
{ name: "Wireless Earbuds", price: 24.99, category: "electronics" },
{ name: "Reusable Tote Bag", price: 4.5, category: "accessories" }
])

updateMany() applies the same update to every document matching the filter, not just the first one — every electronics listing gets onSale: true in one call, instead of one updateOne() per listing.

updateMany — The Same Change, Across Every Match
db.listings.updateMany(
{ category: "electronics" },
{ $set: { onSale: true } }
)

An update doesn't have to replace a whole document — $set changes exactly the fields named and leaves everything else untouched. This single-document write is also atomic: another reader either sees the old price or the new one, never a half-applied change caught in between.

Updating One Field, Not the Whole Document
db.listings.updateOne(
{ _id: "lst-fast-charger-20w" },
{ $set: { price: 7.99 } }
)

Three more targeted update operators, all combinable in one call: $inc changes a number in place without reading it first (raising viewCount by 1, whatever it currently is) — genuinely atomic, so two simultaneous views never lose one of the increments the way "read, add one, write back" could. $push appends a value onto an array field. $unset removes a field entirely.

$inc, $unset, and $push — Beyond $set
db.listings.updateOne(
{ _id: "lst-fast-charger-20w" },
{
$inc: { viewCount: 1 },
$push: { tags: "flash-sale" },
$unset: { discontinuedNote: "" }
}
)

An upsert does one of two things depending on whether a match exists: if a document matches the filter, it updates it, exactly like a normal update; if nothing matches, it creates a brand-new document from the filter and the update combined. One call, either outcome, no separate "does this already exist?" check needed first.

Upsert — Update or Insert in One Call
db.listings.updateOne(
{ _id: "lst-new-item" },
{ $set: { name: "New Item", price: 12.5 } },
{ upsert: true }
)

By 6 a.m., forty new listings exist and every electronics listing carries the sale tag — four calls, not dozens. Batch operations aren't a shortcut around the document model; they're the exact same insertOne()/updateOne() thinking, just told to repeat itself across every document a filter matches, instead of Sarah writing that repetition by hand.

Key Takeaway

insertMany() and updateMany() aren't different operations from insertOne()/updateOne() — they're the same ones, applied across every match in a single call instead of one round trip per document.

Why This Matters

Batch writes come up constantly once GreenMart is a real, growing platform — onboarding a seller's whole catalog at once, a seasonal price change across a category, a data cleanup touching thousands of documents. Knowing insertOne()/updateOne() alone would mean writing a loop for every one of those; insertMany()/updateMany() do it in the one call MongoDB already built for exactly this.

GreenMart's catalog can grow and change at real speed now, not one document at a time. The next chapter is about the opposite direction — what happens the day a listing needs to go the other way, and disappear.

Next