CRUD in MongoDB
Every database boils down to four things you can do with your data: put new records in, read them back, change them, and throw them away. People shorten those four verbs to CRUD — Create, Read, Update, Delete. In MongoDB the “records” are JSON-like documents living inside a collection, and the verbs map onto a small, predictable set of methods that look almost identical whether you type them into the shell or call them from a driver in Node.js, Python, Go, or Rust.
This module is the working heart of the course. By the end of it you will be able to load documents into a collection, pull them back out with filters, surgically change fields without clobbering the rest of a document, remove exactly what you mean to remove, and combine many writes into a single efficient round trip. We will keep the data deliberately small and made-up — a handful of imaginary library members and the books they borrow — so the operations stay in the spotlight.
flowchart LR
App["Your app or mongosh"] -->|"insert / find / update / delete"| Driver["Driver or shell"]
Driver --> Coll["Collection: members"]
Coll --> D1["{ _id, name, fines }"]
Coll --> D2["{ _id, name, fines }"]
Coll --> D3["{ _id, name, fines }"] The four operation families
Section titled “The four operation families”Each family has a singular method that touches at most one document and a plural method that can touch many. Here is the whole vocabulary you will spend this module learning:
- Create —
insertOneadds a single document,insertManyadds an array of them. - Read —
findOnereturns the first matching document (or nothing),findreturns a cursor over every match. - Update —
updateOnechanges the first match,updateManychanges every match. Both use update operators like$setand$inc. - Delete —
deleteOneremoves the first match,deleteManyremoves every match.
The same shape shows up across all five tabs you will see throughout this module. Watch how an insert reads almost the same in the shell and in each driver:
db.members.insertOne({ name: "Ada", fines: 0 })await db.collection("members").insertOne({ name: "Ada", fines: 0 });db.members.insert_one({"name": "Ada", "fines": 0})coll.InsertOne(ctx, bson.M{"name": "Ada", "fines": 0})coll.insert_one(doc! { "name": "Ada", "fines": 0 }).await?;After that insert the stored document looks like this — note the _id that MongoDB added for you:
{ "_id": "65f0a1c2e4b0a1c2e4b0a1c2", "name": "Ada", "fines": 0 }In Compass: the same four families map to the GUI — Compass shows documents in the Documents tab, where you can insert with the green ADD DATA button, edit a field inline, and delete a document with the trash icon that appears on hover.
What this module covers
Section titled “What this module covers”The lessons that follow take each family in turn, then finish with the two power moves that combine families:
- Insert — adding one or many documents, and the automatic
_id. - Read —
findversusfindOne, equality and multi-field filters, and a first taste of projection. - Update —
$set,$inc,$unset,$push,$pull, and reading the match counts a write returns. - Delete — removing documents precisely, plus the soft-delete pattern.
- Upsert and bulk writes — “insert if missing, otherwise update” and packing many operations into one trip to the server.
Tips and gotchas
Section titled “Tips and gotchas”- The singular methods (
insertOne,findOne,updateOne,deleteOne) never affect more than one document, even if many match — handy as a safety rail. - Write methods return an acknowledgement describing what happened (counts, inserted ids). Reading that result is how you confirm an operation did what you intended.
- A filter that matches nothing is not an error. An update or delete that matches zero documents simply reports zero changes.