Chapter 3 of 13
~13 minCRUD Operations
Create, Read, Update, and Delete are the four operations every application performs constantly, and MongoDB gives each one a small, consistent family of methods. Getting comfortable with the "One" vs "Many" variants and their option objects covers the vast majority of day-to-day database work.
Create: insertOne and insertMany
`insertOne()` adds a single document to a collection and returns an acknowledgment containing the generated (or supplied) "_id". `insertMany()` inserts an array of documents in one round trip, which is both more convenient and significantly faster than looping over `insertOne()` for bulk data, since it avoids one network round trip per document.
db.users.insertOne({ name: "Ada", age: 30 })
db.users.insertMany([
{ name: "Grace", age: 45 },
{ name: "Alan", age: 41 },
{ name: "Katherine", age: 38 }
])Read: find and findOne
`find(query)` returns a cursor over every document matching the query filter (an empty object `{}` matches everything), which you typically iterate, convert with `.toArray()`, or chain further with `.sort()`, `.limit()`, and `.skip()`. `findOne(query)` returns only the first matching document (or null), which is convenient when you expect at most one result, such as a lookup by a unique field.
db.users.find({ age: { $gte: 40 } })
.sort({ age: -1 })
.limit(2)
// Only one document expected
db.users.findOne({ name: "Ada" })Update: updateOne, updateMany, and Update Operators
`updateOne(filter, update)` modifies the first document matching the filter; `updateMany(filter, update)` modifies every matching document. The update argument is not a plain replacement document (by default) - it uses update operators like `$set` (change or add fields), `$inc` (increment a number), `$unset` (remove a field), and `$push` (append to an array) to describe precisely what should change, leaving the rest of the document untouched.
Passing `{ upsert: true }` as an option turns the update into an "update or insert": if no document matches the filter, MongoDB inserts a new one built from the filter and update instead of doing nothing.
db.users.updateOne(
{ name: "Ada" },
{ $set: { age: 31 }, $push: { tags: "updated" } }
)
db.users.updateMany(
{ age: { $lt: 18 } },
{ $set: { status: "minor" } }
)
// Insert if no match, update if one exists
db.settings.updateOne(
{ userId: "u1" },
{ $set: { theme: "dark" } },
{ upsert: true }
)Delete: deleteOne and deleteMany
`deleteOne(filter)` removes the first document matching the filter; `deleteMany(filter)` removes every matching document, and passing `{}` to `deleteMany` removes every document in the collection - a command worth double-checking before running against production data.
db.users.deleteOne({ name: "Alan" })
db.users.deleteMany({ status: "inactive" })Coding challenge
Insert two task documents into a "tasks" collection (each with a "title" and "done: false"), mark one of them as done using $set, then delete every task where "done" is true.
// Write your solution here
Answer every question below to mark this chapter as complete.
Quiz Yourself
Score: 0/41. What is the main advantage of insertMany() over calling insertOne() repeatedly in a loop?
2. What does the $set operator do inside an update?
3. What does passing { upsert: true } to updateOne() accomplish?
4. What happens if you call db.users.deleteMany({}) ?