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.
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.
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.
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.
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.
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.
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.
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.
