MongoDB文档删除 #
一、删除概述 #
1.1 删除方法 #
MongoDB提供两种删除方式:
| 方法 | 说明 |
|---|---|
| deleteOne | 删除单个文档 |
| deleteMany | 删除多个文档 |
1.2 删除注意事项 #
| 注意事项 | 说明 |
|---|---|
| 不可恢复 | 删除操作不可逆,建议先备份 |
| 索引保留 | 删除文档不会删除索引 |
| 固定集合 | 固定集合不能删除单个文档 |
二、deleteOne方法 #
2.1 基本删除 #
javascript
// 删除单个文档
db.users.deleteOne({ name: "John" })
// 输出
{
"acknowledged": true,
"deletedCount": 1
}
2.2 条件删除 #
javascript
// 按条件删除
db.users.deleteOne({ _id: ObjectId("507f1f77bcf86cd799439011") })
// 删除第一个匹配的文档
db.users.deleteOne({ status: "inactive" })
2.3 删除选项 #
javascript
// 删除选项
db.users.deleteOne(
{ name: "John" },
{
writeConcern: { w: "majority", j: true },
collation: { locale: "en", strength: 2 }
}
)
三、deleteMany方法 #
3.1 批量删除 #
javascript
// 删除多个文档
db.users.deleteMany({ status: "inactive" })
// 输出
{
"acknowledged": true,
"deletedCount": 10
}
3.2 条件删除 #
javascript
// 删除所有匹配文档
db.users.deleteMany({ age: { $lt: 18 } })
// 复杂条件删除
db.orders.deleteMany({
status: "cancelled",
createdAt: { $lt: new Date("2024-01-01") }
})
// 删除所有文档
db.users.deleteMany({})
3.3 删除选项 #
javascript
// 删除选项
db.users.deleteMany(
{ status: "inactive" },
{
writeConcern: { w: "majority" },
collation: { locale: "en", strength: 2 }
}
)
四、findOneAndDelete #
4.1 查找并删除 #
javascript
// 查找并删除
db.users.findOneAndDelete(
{ name: "John" },
{
projection: { name: 1, email: 1 },
sort: { age: -1 },
maxTimeMS: 5000
}
)
// 输出:返回被删除的文档
{
"_id": ObjectId("..."),
"name": "John",
"email": "john@example.com"
}
4.2 使用场景 #
javascript
// 获取并删除队列中的任务
db.tasks.findOneAndDelete(
{ status: "pending" },
{ sort: { priority: -1, createdAt: 1 } }
)
// 获取并删除最旧的日志
db.logs.findOneAndDelete(
{},
{ sort: { timestamp: 1 } }
)
五、remove方法(已废弃) #
5.1 基本用法 #
javascript
// remove方法(已废弃,不推荐使用)
db.users.remove({ name: "John" })
// 删除单个文档
db.users.remove({ name: "John" }, true)
注意: remove方法已废弃,推荐使用deleteOne和deleteMany。
六、批量删除 #
6.1 bulkWrite删除 #
javascript
// 批量删除操作
db.users.bulkWrite([
{
deleteOne: {
filter: { name: "John" }
}
},
{
deleteMany: {
filter: { status: "inactive" }
}
}
])
// 输出
{
"acknowledged": true,
"deletedCount": 11
}
6.2 分批删除 #
javascript
// 分批删除大量数据
while (true) {
const result = db.logs.deleteMany(
{ timestamp: { $lt: new Date("2024-01-01") } },
{ limit: 1000 }
)
print(`Deleted ${result.deletedCount} documents`)
if (result.deletedCount === 0) break
}
七、删除策略 #
7.1 软删除 #
javascript
// 软删除:标记为已删除
db.users.updateOne(
{ _id: ObjectId("...") },
{
$set: {
deleted: true,
deletedAt: new Date()
}
}
)
// 查询时过滤已删除文档
db.users.find({ deleted: { $ne: true } })
// 定期清理已删除文档
db.users.deleteMany({
deleted: true,
deletedAt: { $lt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) }
})
7.2 TTL索引自动删除 #
javascript
// 创建TTL索引自动删除过期文档
db.logs.createIndex(
{ createdAt: 1 },
{ expireAfterSeconds: 3600 } // 1小时后删除
)
// 修改TTL时间
db.runCommand({
collMod: "logs",
index: {
keyPattern: { createdAt: 1 },
expireAfterSeconds: 7200 // 改为2小时
}
})
7.3 固定集合自动删除 #
javascript
// 固定集合自动删除最旧文档
db.createCollection("logs", {
capped: true,
size: 10485760, // 10MB
max: 10000 // 最多10000个文档
})
八、删除性能 #
8.1 删除优化 #
javascript
// 使用索引加速删除
db.users.createIndex({ status: 1 })
db.users.deleteMany({ status: "inactive" })
// 批量删除
db.users.deleteMany({ status: "inactive" })
// 分批删除大量数据
const batchSize = 1000
while (true) {
const result = db.users.deleteMany(
{ status: "inactive" },
{ limit: batchSize }
)
if (result.deletedCount === 0) break
}
8.2 删除与drop #
javascript
// 删除所有文档(保留索引)
db.users.deleteMany({})
// 删除集合(删除索引)
db.users.drop()
db.createCollection("users")
// 对于大量数据,drop更快
db.users.drop()
九、删除安全 #
9.1 删除前确认 #
javascript
// 删除前查询确认
const count = db.users.countDocuments({ status: "inactive" })
print(`将删除 ${count} 个文档`)
if (count > 0) {
db.users.deleteMany({ status: "inactive" })
}
9.2 备份数据 #
javascript
// 删除前备份
db.users.find({ status: "inactive" }).forEach(doc => {
db.users_backup.insertOne(doc)
})
db.users.deleteMany({ status: "inactive" })
9.3 使用事务 #
javascript
// 使用事务确保数据一致性
const session = db.getMongo().startSession()
session.startTransaction()
try {
db.orders.deleteMany({ userId: ObjectId("...") }, { session })
db.users.deleteOne({ _id: ObjectId("...") }, { session })
session.commitTransaction()
} catch (error) {
session.abortTransaction()
print("删除失败: " + error.message)
}
十、删除错误处理 #
10.1 权限错误 #
javascript
// 处理权限错误
try {
db.users.deleteMany({ status: "inactive" })
} catch (error) {
if (error.code === 13) {
print("权限不足")
}
}
10.2 网络错误 #
javascript
// 处理网络错误
try {
db.users.deleteMany({ status: "inactive" })
} catch (error) {
if (error.name === "MongoNetworkError") {
print("网络错误: " + error.message)
}
}
10.3 固定集合错误 #
javascript
// 固定集合不能删除单个文档
db.logs.deleteOne({ _id: ObjectId("...") })
// 报错:cannot remove from a capped collection
// 解决:使用drop重建
db.logs.drop()
db.createCollection("logs", { capped: true, size: 10485760 })
十一、最佳实践 #
11.1 删除前检查 #
javascript
// 推荐:删除前检查
const count = db.users.countDocuments({ status: "inactive" })
if (count > 1000) {
print("警告:将删除大量文档")
// 确认后执行
}
db.users.deleteMany({ status: "inactive" })
11.2 使用软删除 #
javascript
// 推荐:使用软删除
db.users.updateOne(
{ _id: ObjectId("...") },
{ $set: { deleted: true, deletedAt: new Date() } }
)
// 不推荐:直接删除
db.users.deleteOne({ _id: ObjectId("...") })
11.3 分批删除 #
javascript
// 推荐:分批删除大量数据
const batchSize = 1000
while (true) {
const result = db.users.deleteMany(
{ status: "inactive" },
{ limit: batchSize }
)
if (result.deletedCount === 0) break
}
// 不推荐:一次性删除大量数据
db.users.deleteMany({ status: "inactive" }) // 可能超时
十二、常见问题 #
12.1 删除速度慢 #
javascript
// 原因:索引过多、无索引、大量数据
// 解决:
// 1. 创建索引
db.users.createIndex({ status: 1 })
// 2. 分批删除
while (true) {
const result = db.users.deleteMany({ status: "inactive" }, { limit: 1000 })
if (result.deletedCount === 0) break
}
// 3. 使用drop
db.users.drop()
12.2 删除后空间未释放 #
javascript
// 压缩集合释放空间
db.runCommand({ compact: "users" })
// 重建集合
db.users.drop()
db.createCollection("users")
12.3 误删除恢复 #
javascript
// 使用备份恢复
mongorestore --db mydb --collection users /backup/mydb/users.bson
// 使用oplog恢复(复制集)
// 需要在删除后尽快操作
十三、总结 #
删除操作速查表:
| 方法 | 说明 | 示例 |
|---|---|---|
| deleteOne | 删除单个文档 | db.coll.deleteOne({…}) |
| deleteMany | 删除多个文档 | db.coll.deleteMany({…}) |
| findOneAndDelete | 查找并删除 | db.coll.findOneAndDelete({…}) |
删除选项:
| 选项 | 说明 |
|---|---|
| writeConcern | 写关注 |
| collation | 排序规则 |
| limit | 限制删除数量 |
下一步,让我们学习基础查询!
最后更新:2026-03-27