MongoDB 删除文档

MongoDB 删除文档完整指南

(MongoDB 8.0+,2025 年最新实践)

核心结论
删除文档 = deleteOne() / deleteMany()
不可逆操作! 生产环境 必须备份 + 软删除优先


一、核心删除命令对比

命令匹配条件删除数量推荐场景
deleteOne(filter)第一个 匹配的文档1删除单条
deleteMany(filter)所有 匹配的文档N批量删除

二、基本删除示例

use company

// 1. 删除单个员工(第一个匹配)
db.employees.deleteOne({ name: "张三" })
// 返回:{ acknowledged: true, deletedCount: 1 }

// 2. 删除所有离职员工
db.employees.deleteMany({ status: "离职" })
// 返回:{ acknowledged: true, deletedCount: 15 }

// 3. 删除 _id 指定的文档
db.employees.deleteOne({ _id: ObjectId("671f2a1b9d8e4c2a7f1b3d5e") })

三、删除返回结果解析

{
  "acknowledged": true,
  "deletedCount": 3
}
  • acknowledged: true → 操作被服务器接受
  • deletedCount → 实际删除的文档数量

注意:如果 deletedCount: 0,说明未找到匹配文档


四、软删除(推荐生产!)

不要物理删除,用字段标记

// 1. 标记删除(推荐)
db.employees.updateOne(
  { name: "李四" },
  { 
    $set: { 
      deleted: true,
      deletedAt: new Date(),
      deletedBy: "admin"
    }
  }
)

// 2. 查询时自动过滤
db.employees.find({ deleted: { $ne: true } })

// 3. 定期归档(可选)
db.deleted_employees.insertOne(
  db.employees.findOneAndDelete({ name: "李四" })
)

五、findOneAndDelete(查找并删除)

返回被删除的原始文档

// 获取并删除文档(常用于归档)
const doc = db.employees.findOneAndDelete(
  { name: "王五" },
  { sort: { hireDate: -1 } }  // 可选:按条件排序后删除
)

printjson(doc)  // 打印被删除的文档

六、批量删除(高性能)

// 删除 30 天前的日志
db.logs.deleteMany({
  timestamp: { $lt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) }
})

// 删除临时用户(未激活)
db.users.deleteMany({
  status: "pending",
  createdAt: { $lt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) }
})

七、权限要求

操作所需角色
deleteOne / deleteManyreadWrite
跨库删除readWriteAnyDatabaseroot
// 创建有删除权限的用户
use admin
db.createUser({
  user: "operator",
  pwd: "Op2025!",
  roles: [{ role: "readWrite", db: "company" }]
})

八、事务中删除(4.0+)

const session = db.getMongo().startSession();
session.startTransaction();

try {
  db.orders.deleteOne({ orderId: "O001" }, { session });
  db.inventory.updateOne(
    { productId: "P001" },
    { $inc: { stock: 1 } },
    { session }
  );
  session.commitTransaction();
} catch (error) {
  session.abortTransaction();
  throw error;
} finally {
  session.endSession();
}

九、性能优化建议

场景优化方式
批量删除使用 deleteMany + 索引过滤
高并发避免锁表,建议软删除
大集合分批删除(limit + 循环)
// 分批删除(每批 1000 条)
let deleted = 0;
while (true) {
  const result = db.logs.deleteMany(
    { level: "debug", timestamp: { $lt: ISODate("2024-01-01") } },
    { limit: 1000 }
  );
  deleted += result.deletedCount;
  if (result.deletedCount === 0) break;
}
print(`共删除 ${deleted} 条日志`);

十、验证删除结果

// 1. 查看删除统计
db.employees.deleteMany({ ... })
// → deletedCount

// 2. 确认数据已删除
db.employees.countDocuments({ name: "张三" })  // 应为 0

// 3. 查看软删除标记
db.employees.find({ deleted: true }).count()

十一、GUI 工具删除文档

工具操作
MongoDB Compass文档 → 右键 → Delete Document
VS Code + MongoDB文档 → 右键 → Delete Document
MongoDB Atlas文档 → Delete

十二、常见错误与解决方案

错误原因解决方案
not authorized权限不足检查用户角色
WriteConcernError副本集不可用检查集群状态
deletedCount: 0未匹配到文档检查过滤条件
ImmutableField尝试删除 _id不可删除

十三、完整删除脚本示例

// delete_data.js
use company

print("开始清理无效数据...")

// 1. 软删除过期临时用户
const softDelete = db.users.updateMany(
  {
    status: "temp",
    createdAt: { $lt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000) }
  },
  {
    $set: {
      deleted: true,
      deletedAt: new Date(),
      reason: "timeout"
    }
  }
)
print(`软删除 ${softDelete.modifiedCount} 个临时用户`)

// 2. 物理删除 90 天前日志
const hardDelete = db.logs.deleteMany({
  timestamp: { $lt: new Date(Date.now() - 90 * 24 * 60 * 60 * 1000) }
})
print(`物理删除 ${hardDelete.deletedCount} 条旧日志`)

// 3. 归档并删除高危记录
const archived = db.audit.findOneAndDelete(
  { level: "critical", action: "drop_database" }
)
if (archived) {
  db.audit_archive.insertOne(archived)
  print("高危操作已归档")
}

print("数据清理完成!")

运行:

mongosh delete_data.js

十四、一句话总结

**“MongoDB 删除文档 = deleteOne/Many() + *软删除优先* + 事务/备份”**


快速删除模板

// 单条删除
db.posts.deleteOne({ _id: ObjectId("...") })

// 批量删除
db.sessions.deleteMany({ expired: true })

// 软删除
db.users.updateOne({ id: 123 }, { $set: { deleted: true, deletedAt: new Date() } })

// 查找并归档删除
db.temp.findOneAndDelete({ type: "cache" })

官方文档

  • https://www.mongodb.com/docs/manual/reference/method/db.collection.deleteOne/
  • https://www.mongodb.com/docs/manual/reference/method/db.collection.deleteMany/

如需 定时清理脚本软删除 + 自动归档从 SQL DELETE 迁移Change Streams 监听删除,欢迎继续提问!

文章已创建 2349

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部