01. 插入文档——insertOne / insertMany
插入数据是 CRUD 的第一个操作。MongoDB 提供 insertOne(插一条)和 insertMany(插多条)。
insertOne 插入一个文档,如果集合不存在会自动创建。返回值包含 insertedId——自动生成的 _id。insertMany 可以一次插入多条,效率高很多。
批量插入时可以加 ordered: false 参数——即使中间某条插入失败,后面的继续插,不会全部回滚。默认 ordered: true 会按顺序插,遇到错误就停止。
javascript
// 插入一条
db.users.insertOne({
name: "Alice",
email: "[email protected]",
age: 36
});
// 插入多条
db.users.insertMany([
{ name: "Bob", email: "[email protected]", age: 42 },
{ name: "Charlie", email: "[email protected]", age: 35 }
]);
// 忽略失败继续插
db.users.insertMany([...], { ordered: false });02. 查询文档——find 与查询条件
find 是 MongoDB 里最重要的命令,相当于 SQL 的 SELECT。find 接收两个参数:查询条件(相当于 WHERE)和投影(相当于 SELECT 哪些列)。
查询条件是一个 JS 对象,字段名 冒号 字段值。特殊操作符以美元符号开头:美元 gt(大于)、美元 lt(小于)、美元 gte(大于等于)、美元 lte(小于等于)、美元 ne(不等于)、美元 in(在列表里)。
逻辑操作符:美元 and(且)、美元 or(或)、美元 not(非)。多个条件写在一起默认就是 AND 的关系。
findOne 只返回第一条匹配的文档,find 返回游标,可以接着分页排序。
javascript
// 基本查询
db.users.find({ age: { $gt: 30 } });
// 多条件查询
db.users.find({
age: { $gte: 20, $lte: 40 },
email: /@example\.com$/
});
// $or
db.users.find({
$or: [{ age: { $lt: 20 } }, { age: { $gt: 50 } }]
});
// 投影——只返回 name 和 email
db.users.find({}, { name: 1, email: 1, _id: 0 });find 返回游标,惰性加载,不是一次性把所有数据取回来。默认前 20 条,用 it 查看更多。
03. 更新文档——updateOne / updateMany
更新操作分三种:updateOne(改第一条匹配的)、updateMany(改所有匹配的)、replaceOne(把整个文档换成新的)。
更新操作符:美元 set——设某个字段的值;美元 unset——删除某个字段;美元 inc——给数字字段加减一个值;美元 push——数组尾部加一个元素;美元 pull——数组中删除匹配的元素;美元 rename——改字段名。
upsert 选项:如果找不到匹配的文档,就插入一条。updateOne 配合 upsert: true 很好用——有就改,没有就建。
javascript
// 改一条
db.users.updateOne(
{ name: "Alice" },
{ $set: { age: 37 } }
);
// 批量改
db.users.updateMany(
{ age: { $gte: 40 } },
{ $set: { tag: "senior" } }
);
// $inc:全体年龄 +1
db.users.updateMany({}, { $inc: { age: 1 } });
// $push:添加兴趣
db.users.updateOne(
{ name: "Alice" },
{ $push: { hobbies: "golf" } }
);
// upsert
db.users.updateOne(
{ name: "David" },
{ $set: { age: 55 } },
{ upsert: true }
);updateOne 只改第一条匹配的,updateMany 改所有匹配的。别用混了。
04. 删除文档——deleteOne / deleteMany
删除分 deleteOne 和 deleteMany。deleteMany 传空对象会删光整个集合的所有文档(但集合还在)。
删除操作返回一个结果对象,包含 deletedCount——告诉你删了几条。如果删除条件匹配了很多文档,可以中途用 killOp 终止。
清空集合最快的办法是 drop()——直接删集合(包括索引),比 deleteMany({}) 快得多,因为 drop 不逐个删文档,直接回收空间。但 drop 连索引一起删,重建索引有成本。
安全建议:生产环境先 find 看看匹配多少条,确认没问题再 delete。删除操作最好先在测试库跑一遍。
javascript
// 删一条
db.users.deleteOne({ name: "Alice" });
// 删所有匹配的
db.users.deleteMany({ age: { $lt: 18 } });
// 删集合里所有文档(保留集合结构)
db.users.deleteMany({});
// 直接删集合(快但索引也丢)
db.users.drop();
// 安全删除——先看再删
const count = db.users.countDocuments({ age: { $lt: 18 } });
print('将要删除 ' + count + ' 条');deleteMany({}) 删全部数据但保留集合,drop() 连集合带索引全删。生产环境操作前先做备份。
05. CRUD 操作实战——一个完整的用户管理场景
把 insertOne、find、updateOne、deleteOne 串起来做一个完整的用户管理场景:
1. 创建用户——insertOne 插入新用户,检查邮箱是否重复(用唯一索引或先 findOne 检查)。
2. 查找用户——find 支持模糊搜索(正则匹配姓名)、按年龄范围筛选、分页展示。
3. 更新用户信息——updateOne 加 dollar set 只改需要改的字段,用 dollar inc 修改积分累计。
4. 删除用户——deleteOne 按照用户 ID 精确删除。或 deleteMany 批量删除过期的未激活用户。
完整的 CRUD 操作记住个规律:条件在前(第一个参数),操作在后(第二个参数)。每一类操作都是这个结构。
还有一个常用技巧:增删改之后用 find 验证一下。比如 insert 后把新文档查出来确认字段都对。开发阶段这个习惯很省排查时间。
javascript
// 完整 CRUD 场景
// 1. 检查重复 + 插入
get existing = db.users.findOne({ email: "[email protected]" });
if (!existing) {
db.users.insertOne({
name: "New User",
email: "[email protected]",
age: 25,
points: 0,
createdAt: new Date()
});
}
// 2. 模糊搜索 + 分页
db.users.find({
name: /new/i, // 不区分大小写的模糊匹配
age: { $gte: 18 }
}).sort({ createdAt: -1 }).skip(0).limit(10);
// 3. 更新积分
db.users.updateOne(
{ email: "[email protected]" },
{ $inc: { points: 10 }, $set: { lastLogin: new Date() } }
);
// 4. 批量清理
db.users.deleteMany({
createdAt: { $lt: new Date("2023-01-01") },
points: 0
});MongoDB 的 CRUD 和 SQL 的 CRUD 本来就是一回事——增(Insert)、查(Select)、改(Update)、删(Delete)。语法不同但逻辑相通。
知识测验
第 1/5 题正确 0
insertMany 的 ordered: false 干什么的?
下一节
下一节 高级查询