CRUD 操作
insert/find/update/delete。
30 分钟
CRUD 操作
这一课你将能做到
- 熟练使用 insertOne/insertMany、find/findOne、updateOne/updateMany/replaceOne、deleteOne/deleteMany 完成全部增删改查
- 用
$set/$inc/$push等更新运算符做「原地修改」,并说出它和整文档替换的区别 - 用 bulkWrite 做批量写,并解释 upsert 与 findOneAndUpdate 的实际用途
为什么要学
CRUD 是 MongoDB 的日常:用户提交一次代码,就是一次 insert;做完一节课,进度集合就是一次 upsert + $inc;后台清洗脏数据,就是 updateMany/deleteMany。写错一个更新运算符,比如把 $set 写成整文档替换,可能瞬间把用户文档里其它字段全部抹掉——这是真实发生过的生产事故。
人话:查询是「读空气」,更新是「动手术」。读错了再读一次就行,写错了数据就真没了,所以这一课的重点在写。
先建立图像
更新运算符 vs 整文档替换的区别:
原文档: { userId: 1024, doneCount: 3, nickname: "小明", city: "上海" }
$set 更新(手术刀,只动指定字段):
db.users.updateOne({userId:1024}, {$set: {doneCount: 4}})
结果: { userId: 1024, doneCount: 4, nickname: "小明", city: "上海" } ✅ 其它字段还在
replaceOne(推土机,整个文档换掉):
db.users.replaceOne({userId:1024}, {doneCount: 4})
结果: { _id: ..., doneCount: 4 } ❌ nickname/city/userId 全没了!
跟着做
准备演示数据:
use codeforge
db.submissions.drop()
db.submissions.insertMany([
{ userId: 1024, lessonSlug: "mdbrm-intro", status: "accepted", score: 100, attempts: 1, submittedAt: new Date("2026-10-01") },
{ userId: 1024, lessonSlug: "mdbrm-types", status: "failed", score: 40, attempts: 2, submittedAt: new Date("2026-10-02") },
{ userId: 2048, lessonSlug: "mdbrm-intro", status: "accepted", score: 90, attempts: 3, submittedAt: new Date("2026-10-03") }
])
步骤 1:Create —— 插入
// 单条
db.submissions.insertOne({ userId: 2048, lessonSlug: "mdbrm-types", status: "pending", score: 0, attempts: 1 })
// 多条:ordered 默认 true,遇错即停
db.submissions.insertMany([
{ userId: 4096, lessonSlug: "mdbrm-intro", status: "accepted", score: 85 },
{ userId: 4096, lessonSlug: "mdbrm-types", status: "accepted", score: 92 }
], { ordered: false }) // false:跳过错误继续插
步骤 2:Read —— 查询基础
// 等值
db.submissions.find({ userId: 1024 })
// 多条件(隐式 AND)
db.submissions.find({ userId: 1024, status: "accepted" })
// 只取一条
db.submissions.findOne({ lessonSlug: "mdbrm-types" }, { score: 1, status: 1 })
find 返回的是游标,mongosh 自动迭代前 20 条,输入 it 继续翻。