P3. CRUD 操作 — 增删改查从零开始
CRUD 操作就像操作一个没有固定列的 Excel 表。
普通 Excel 表:每列都是定好的(A列=姓名,B列=年龄),你不能第一行填3列、第二行填7列。
MongoDB 的"Excel":每一行想填几列就填几列!第一行可以只有品名和价格,第二行可以再加上配料、甜度、备注、送餐地址…没人管你。
• insertOne = 往 Excel 里加一行,想填几列就填几列
• find = 在 Excel 里筛选(但支持嵌套条件,比普通筛选强得多)
• update = 修改某个单元格(⚠️ 但记住用 $set 只改这一格,忘了 $set 会清空整行重写!)
• delete = 删除一行
➕ Insert — 插入数据
> use milk_tea_shop
switched to db milk_tea_shop
> db.orders.insertOne({
orderNo: "ORD20250112001",
customer: { name: "张三", phone: "138****1234" },
items: [
{ product: "经典套餐A", price: 15, qty: 2 },
{ product: "芝士莓莓", price: 22, qty: 1 }
],
totalAmount: 52,
status: "paid",
createdAt: new Date()
})
{
"acknowledged": true,
"insertedId": ObjectId("65a1b2c3d4e5f6a7b8c9d0")
}
> db.orders.insertMany([
{ orderNo: "ORD002", totalAmount: 30, status: "pending" },
{ orderNo: "ORD003", totalAmount: 45, status: "paid" },
{ orderNo: "ORD004", totalAmount: 18, status: "cancelled" }
])
{
"acknowledged": true,
"insertedIds": [
ObjectId("65a1b2c3..."),
ObjectId("65a1b2c4..."),
ObjectId("65a1b2c5...")
]
}
⚠️ 注意:insertMany 默认是有序的(ordered: true),中间某条失败会停止后续插入。如果不在乎顺序,用 insertMany([...], {ordered: false}) 让成功的先插入。
🔍 Find — 查询数据
> db.orders.find({})
> db.orders.find({ status: "paid" })
> db.orders.find({ totalAmount: { $gt: 30 } })
> db.orders.find({ totalAmount: { $gte: 30 } })
> db.orders.find({ totalAmount: { $lt: 50 } })
> db.orders.find({ totalAmount: { $lte: 50 } })
> db.orders.find({ totalAmount: { $ne: 52 } })
> db.orders.find({ totalAmount: { $gte: 20, $lte: 50 } })
> db.orders.find({ status: { $in: ["paid", "shipped"] } })
> db.orders.find({ status: "paid", totalAmount: { $gt: 30 } })
> db.orders.find({
$or: [
{ status: "paid" },
{ totalAmount: { $lt: 20 } }
]
})
> db.orders.find({ "customer.name": "张三" })
> db.orders.find({ "items.product": "经典套餐A" })
🎯 投影 — 只返回需要的字段
> db.orders.find(
{ status: "paid" },
{ orderNo: 1, totalAmount: 1 }
)
{ _id: ObjectId("..."), orderNo: "ORD001", totalAmount: 52 }
> db.orders.find(
{ status: "paid" },
{ _id: 0, orderNo: 1, totalAmount: 1 }
)
{ orderNo: "ORD001", totalAmount: 52 }
> db.orders.find({}, { items: 0, customer: 0 })
{ _id: ..., orderNo: "ORD001", totalAmount: 52, status: "paid", createdAt: ... }
📝 Update — 更新数据
> db.orders.updateOne({ orderNo: "ORD001" }, { status: "shipped" })
// 结果:文档变成 { _id:..., status: "shipped" } — 其他字段全没了!
> db.orders.updateOne(
{ orderNo: "ORD001" },
{ $set: { status: "shipped", updatedAt: new Date() } }
)
{ acknowledged: true, matchedCount: 1, modifiedCount: 1 }
> db.orders.updateOne(
{ orderNo: "ORD001" },
{
$set: { status: "delivered" },
$inc: { totalAmount: 5 },
$push: { "items": { product: "布丁", price: 3, qty: 1 } },
$unset: { note: "" }
}
)
> db.orders.updateMany(
{ status: "pending" },
{ $set: { status: "cancelled", cancelReason: "超时未支付" } }
)
> db.orders.updateOne(
{ orderNo: "ORD999" },
{ $set: { totalAmount: 100, status: "new" } },
{ upsert: true }
)
{ acknowledged: true, upsertedId: ObjectId("..."), matchedCount: 0, modifiedCount: 0 }
⚠️ 生产必看:忘记 $set 的后果
updateOne({_id:xxx}, {name:"新名字"}) — 没有 $set!
结果:整个文档变成 {_id:xxx, name:"新名字"},其他字段全部丢失!
这是 MongoDB 新手最常犯的错误之一。记住:更新操作一定要带操作符($set、$inc、$push 等)!
❌ Delete — 删除数据
> db.orders.deleteOne({ orderNo: "ORD004" })
{ acknowledged: true, deletedCount: 1 }
> db.orders.deleteMany({ status: "cancelled" })
{ acknowledged: true, deletedCount: 5 }
> db.orders.deleteMany({})
⚠️ 生产建议:和 MySQL 一样,生产环境用软删除(加 deleted: true 字段),不要真删!