文档的删除(deleteOne、deleteMany)
文档的删除(deleteOne、deleteMany)
MongoDB提供了两种主要的文档删除方法:deleteOne
和deleteMany
。这两种方法分别用于删除单个文档和多个文档,是数据库操作中常用的功能。
deleteOne方法
deleteOne
方法用于删除集合中匹配条件的第一个文档。如果匹配到多个文档,只会删除第一个匹配的文档。
// 示例:删除users集合中name为"张三"的第一个文档
const result = await db.collection('users').deleteOne({ name: "张三" });
console.log(result.deletedCount); // 输出被删除的文档数量
deleteOne
方法返回一个Promise,解析后的对象包含以下属性:
deletedCount
:被删除的文档数量(0或1)acknowledged
:操作是否被确认(布尔值)
deleteMany方法
deleteMany
方法用于删除集合中所有匹配条件的文档。
// 示例:删除users集合中所有age大于30的文档
const result = await db.collection('users').deleteMany({ age: { $gt: 30 } });
console.log(result.deletedCount); // 输出被删除的文档总数
deleteMany
返回的对象结构与deleteOne
类似,但deletedCount
可能大于1。
删除条件的使用
删除操作的条件语法与查询操作相同,可以使用各种查询操作符:
// 使用比较操作符
await db.collection('products').deleteMany({ price: { $lt: 100 } });
// 使用逻辑操作符
await db.collection('users').deleteMany({
$or: [
{ status: "inactive" },
{ lastLogin: { $lt: new Date(Date.now() - 30*24*60*60*1000) } }
]
});
// 使用数组操作符
await db.collection('articles').deleteMany({ tags: { $in: ["obsolete", "deprecated"] } });
删除操作的注意事项
-
原子性:MongoDB中的删除操作在单个文档级别是原子的。对于多个文档的删除,每个文档的删除是原子的,但整个操作不是原子的。
-
性能影响:大量文档的删除可能影响数据库性能,特别是在生产环境中。
-
索引使用:删除操作会利用索引来提高性能,但也会导致索引维护开销。
-
存储空间:删除文档不会自动释放磁盘空间,需要使用
compact
命令或repairDatabase
命令来回收空间。
删除操作的替代方案
在某些情况下,可能不希望实际删除文档,而是采用"软删除"模式:
// 软删除示例:添加deleted字段标记文档为已删除
await db.collection('orders').updateMany(
{ status: "cancelled" },
{ $set: { deleted: true, deletedAt: new Date() } }
);
这种模式允许恢复"删除"的数据,同时保持引用完整性。
删除操作与事务
在MongoDB 4.0+中,删除操作可以包含在事务中:
const session = db.client.startSession();
try {
await session.withTransaction(async () => {
await db.collection('users').deleteOne({ _id: userId }, { session });
await db.collection('profiles').deleteOne({ userId }, { session });
});
} finally {
session.endSession();
}
删除操作的错误处理
删除操作可能因各种原因失败,应该妥善处理错误:
try {
const result = await db.collection('logs').deleteMany({ createdAt: { $lt: cutoffDate } });
if (result.deletedCount === 0) {
console.log('没有找到匹配的文档');
}
} catch (error) {
console.error('删除操作失败:', error);
}
删除操作的监控
可以通过MongoDB的监控工具跟踪删除操作:
// 获取删除操作的统计信息
const stats = await db.command({ collStats: "users" });
console.log('删除操作次数:', stats.deleted);
删除操作的权限控制
MongoDB提供了细粒度的权限控制,可以限制删除操作:
// 创建只能删除特定条件文档的角色
db.createRole({
role: "limitedDeleteRole",
privileges: [{
resource: { db: "mydb", collection: "orders" },
actions: ["delete"],
conditions: [{ "q.$.status": { $eq: "cancelled" } }]
}],
roles: []
});
删除操作的性能优化
对于大规模删除操作,可以考虑以下优化策略:
- 分批删除:
const batchSize = 1000;
let deletedCount = 0;
do {
const result = await db.collection('tempData').deleteMany({}, { limit: batchSize });
deletedCount = result.deletedCount;
console.log(`已删除 ${deletedCount} 个文档`);
} while (deletedCount > 0);
-
在低峰期执行大规模删除操作
-
删除前临时禁用索引
删除操作与副本集
在副本集环境中,删除操作会传播到所有副本节点。可以配置写关注(Write Concern)来控制确认级别:
// 等待删除操作传播到大多数节点
await db.collection('auditLogs').deleteMany(
{ retentionDate: { $lt: new Date() } },
{ writeConcern: { w: "majority" } }
);
删除操作与分片集群
在分片集群中,删除操作会被路由到包含目标文档的分片:
// 删除分片集合中的文档
await db.collection('shardedData').deleteOne({ _id: shardKeyValue });
对于跨分片的删除操作,mongos会协调各个分片的操作。
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn