MongoDB from Basics to Production · MongoDB Basics

Documents and CRUD Operations

Insert, find, update and delete documents with the MongoDB shell, using update operators and upserts instead of replacing whole documents.

Create a free account to save this page, take notes and track your progress. Sign in

What you'll build

A small product catalogue in a products collection: insert documents, read them back, change prices and stock with update operators, upsert a record, and delete one. Every example in this course was run against MongoDB 9.0 with mongosh, in a fresh database, and the output shown is what it printed.

The idea

  • MongoDB stores documents (BSON, like JSON with more types) in collections. Each document has a unique _id.
  • CRUD: insertOne/insertMany, find/findOne, updateOne/updateMany, deleteOne/deleteMany.
  • Update with operators ($set, $inc, $push, $unset) to change only specific fields; replaceOne replaces the whole document.
  • upsert: true inserts the document if nothing matches.

The code

Create, read, update and delete
db.products.insertMany([
  { _id: 1, name: "Mug", category: "kitchen", price: 8.5, stock: 40, tags: ["ceramic", "gift"] },
  { _id: 2, name: "Teapot", category: "kitchen", price: 24, stock: 5, tags: ["cast-iron"] },
  { _id: 3, name: "Kettle", category: "appliances", price: 31.9, stock: 0, tags: ["electric"] },
  { _id: 4, name: "Tea sampler", category: "food", price: 12, stock: 120, tags: ["gift", "organic"] },
]);

printjson(db.products.findOne({ _id: 2 }, { _id: 0, name: 1, price: 1, stock: 1 }));

db.products.updateOne({ _id: 2 }, { $inc: { stock: -1 }, $set: { price: 26 } });
db.products.updateMany({ category: "kitchen" }, { $push: { tags: "bestseller" } });
const up = db.products.updateOne({ _id: 5 }, { $set: { name: "Cup", price: 6, stock: 10 } }, { upsert: true });
print("upserted documents:", up.upsertedCount);
db.products.deleteOne({ _id: 3 });

db.products.find({}, { _id: 1, name: 1, price: 1, stock: 1, tags: 1 }).sort({ _id: 1 })
  .forEach(p => print(p._id, p.name, p.price, p.stock, JSON.stringify(p.tags ?? [])));
print("documents:", db.products.countDocuments());

Output

{
  name: 'Teapot',
  price: 24,
  stock: 5
}
upserted documents: 1
1 Mug 8.5 40 ["ceramic","gift","bestseller"]
2 Teapot 26 4 ["cast-iron","bestseller"]
4 Tea sampler 12 120 ["gift","organic"]
5 Cup 6 10 []
documents: 4

Run this on your computer — see “Get Started” for setup.

Common mistakes

  • Using replaceOne (or updateOne with a plain document in old drivers) and wiping fields you didn't mention.
  • Read-modify-write in application code (find, change, save) instead of atomic operators like $inc; concurrent requests overwrite each other.
  • Relying on auto-generated _id order for "latest" records instead of a timestamp field.

Key points

  • Documents live in collections and have a unique _id.
  • Update with operators like $set, $inc and $push; they're atomic per document.
  • upsert inserts when nothing matches.

Further reading: MongoDB CRUD operations · Update operators

Practice questions

What's the difference between updateOne with $set and replaceOne?

Answer

$set changes only the listed fields; replaceOne replaces the entire document (except _id) with the new one.

Why use $inc instead of reading, adding and writing back a value?

Answer

$inc is atomic on the server, so concurrent updates don't overwrite each other.

What does upsert: true do?

Answer

If no document matches the filter, the update inserts a new document built from the filter and update.

Open in the app to mark lessons complete, take notes and track your progress.

Was this page helpful?