- 后端
- 前端
- 开发工具
- 移动开发
【免费下载链接】meteor
Meteor, the JavaScript App Platform
软删除(Soft Delete)是指删除数据时不真正从数据库移除记录,而是通过打标记的方式将其"隐藏",从而保留审计轨迹、支持数据恢复。jam:soft-delete是 Meteor 生态中一个零配置、同构(Isomorphic)的软删除社区包,它自动覆盖removeAsync、自动为查询注入过滤条件,并额外提供softRemoveAsync、recoverAsync等便捷方法。读完本文,你将掌握该包的安装步骤、永久删除与显式软删除的完整用法、可恢复机制,以及全局配置项的全部细节,并能结合 Meteor 集合 API 的源码实现理解其底层工作原理。
这个包是什么?
jam:soft-delete为 Meteor 应用提供了一键式的软删除能力。其核心特性如下:
- 零配置:开箱即用,同时支持按需定制;
- 同构(Isomorphic):客户端与服务端行为一致,天然配合 Meteor 的 Optimistic UI(乐观 UI)体验;
- 自动覆盖
removeAsync:将原本物理删除的调用转化为软删除; - 自动处理新增与查询:在
insertAsync时自动附加软删除标记字段,并自动为.find等查询追加过滤条件,无需修改任何现有查询代码; - 提供
recoverAsync集合方法:一键恢复被软删除的文档; - 提供
softRemoveAsync集合方法:需要显式软删除时的可选用法; - 可选
deletedAt时间戳:为文档附加删除时间字段; - 可选排除指定集合:某些集合(如角色表)保持物理删除;
- 兼容性:支持 Meteor
2.8.1+与3.0+。
注意:软删除的另一种替代方案是把文档归档到专门的归档集合。若你倾向归档方案,可使用
jam:archive包。建议对比两种方案后,为你的应用选择最合适的一种。
从社区包索引 index.md 可以看到,jam:soft-delete被归类在 "MongoDB collection extensions"(MongoDB 集合扩展)类别下,同类的还有jam:archive与jam:mongo-transactions,均由社区开发者维护。
如何安装?
在应用根目录执行:
meteor add jam:soft-delete该包由社区开发者 Jam 维护(可在 soft-delete 文档 顶部查看维护者信息),源码托管在其 GitHub 仓库。
如何使用?
安装完成后,包的默认行为会自动生效,你的现有代码几乎不需要改动。
永久删除(物理删除)
默认情况下,该包会覆盖集合的removeAsync方法,使其只打软删除标记而不会真正删除文档。如果确实需要从数据库中永久移除,请传入soft: false选项:
Collection.removeAsync(/* your filter */, { soft: false });如果你不希望覆盖removeAsync的行为,可以设置overrideRemove: false,详见下文 配置(可选) 一节。
显式软删除
如果你倾向在代码中明确表达"这是一次软删除",可以使用softRemoveAsync:
Collection.softRemoveAsync(/* your filter */);恢复被软删除的文档
要恢复一条(或多条)被软删除的文档,使用recoverAsync:
Collection.recoverAsync(/* your filter */);这三个方法均接受与removeAsync一致的过滤器(selector),可用于按_id、按条件批量操作等场景。
配置(可选)
如果你满意默认行为,则完全无需任何配置。但该包在默认值之外仍保留了相当大的灵活性。
全局默认配置如下:
const config = { deleted: 'deleted', // 布尔标记字段名,可按需修改,例如改为 'isDeleted' deletedAt: '', // 如需在文档上记录删除时间戳,在此填写字段名,例如 'deletedAt' autoFilter: true, // 自动为查询追加 { [deleted]: false } 过滤条件 overrideRemove: true, // 覆盖 Collection.removeAsync 方法,将其变为软删除 exclude: ['roles', 'role-assignment'] // 排除使用软删除的集合;默认排除 meteor roles 包创建的集合 };各配置项的作用与建议如下:
| 配置项 | 默认值 | 说明 |
|---|---|---|
deleted | 'deleted' | 软删除布尔标记字段名。改动后,所有自动注入的查询条件与标记逻辑都会跟随新字段名。 |
deletedAt | ''(空字符串,即不启用) | 填入字段名(如'deletedAt')后,软删除时会自动为该文档写入删除时间戳。 |
autoFilter | true | 是否自动为.find等查询注入{ deleted: false }过滤条件,使被删文档默认不可见。 |
overrideRemove | true | 是否覆盖removeAsync。设为false后removeAsync恢复为物理删除。 |
exclude | ['roles', 'role-assignment'] | 命中这些名称的集合不启用软删除,删除时仍为物理删除。默认排除 meteor roles 包创建的集合,避免影响权限数据。 |
修改全局默认值的方式如下:
// 放在一个同时被客户端和服务端导入的文件中 import { SoftDelete } from 'meteor/jam:soft-delete'; SoftDelete.configure({ // ... 在此修改默认配置 ... // });配置时请注意:
- 该配置调用必须放置在同时被客户端和服务端导入的文件里,以保证两端行为一致(这也是同构包的基本要求);
- 若你已使用
aldeed:collection2或jam:easy-schema这类自动校验写入的包,软删除标记字段最好同步纳入你的 schema 定义,以免校验拦截; exclude中的集合名是集合在 Mongo 中的实际名称(即new Mongo.Collection('roles')中的'roles')。
底层原理:为什么能做到"零改动"?
要理解该包为何能"自动生效",需要先了解 Meteor 集合的*Async方法族。
Meteor 从2.8.1起引入了 Promise 风格的异步集合方法,insertAsync、removeAsync、updateAsync等与同步版insert、remove、update并存,且旧的同步写法在服务端已标记为 deprecated。这一点可以从 mongo.d.ts 的类型声明中看到:
insert(doc, callback?)被标注为@deprecated on server since 2.8,并注明@see insertAsync;remove(selector, callback?)同样被标注 deprecated,指向removeAsync;insertAsync(doc, callback?)返回Promise<string>(新文档的_id);removeAsync(selector, callback?)返回Promise<number>(删除影响的文档数)。
在实现层面,methods_async.js 中insertAsync经由_insertAsync完成 _id 生成、远端集合(客户端)走 DDP 方法调用、本地集合直接下钻到 driver 的逻辑;而 removeAsync 则先通过Mongo.Collection._rewriteSelector重写选择器,再区分远端与本地集合分别处理。正是这种"集合方法即调用点"的架构,使得jam:soft-delete可以通过覆盖removeAsync、insertAsync与查询过滤器来拦截全部读写路径——这也是它能做到"不改任何查询代码"的根基。
从代码结构可以推断,该包的典型实现思路是:
- 覆盖
removeAsync:当overrideRemove: true时,removeAsync(selector)不再执行物理删除,而是转为对匹配文档执行一次update,将deleted字段置为true(若配置了deletedAt,则一并写入时间戳); insertAsync附加默认标记:新插入的文档会自动带上{ deleted: false },保证所有文档都拥有一致的标记字段,查询过滤才成立;- 查询过滤器注入:当
autoFilter: true时,包会拦截.find/.findOne等查询的 selector,自动追加{ deleted: false },从而让被软删除的文档对业务查询"隐形"; softRemoveAsync与recoverAsync:分别是对上述软删除操作与反向恢复操作的显式封装,recoverAsync将匹配文档的deleted重置为false(或移除标记),使文档重新出现在常规查询结果中。
需要强调的是,上述第 2~4 点的具体实现细节在仓库内以jam:soft-delete包源码为准;从本仓库现有资料可以确证的是:Meteor 集合的*Async方法族(含removeAsync、insertAsync)是包被覆盖的挂载点,且其 Promise 返回约定(insertAsync返回新文档_id、removeAsync返回受影响文档数)定义了各方法之间相互协作的接口形态。
关于兼容性说明
文档明确声明该包兼容 Meteor2.8.1+与3.0+,这与 Meteor 的*Async方法族引入时间(2.8.1)完全吻合——包的默认行为依赖这些异步方法的存在。若你的应用仍停留在2.8.1之前的版本,需要先升级 Meteor 再使用本包。
与其他社区包的配合
jam:soft-delete并非孤立存在,它与 Jam 系列的其他包可以协同工作:
jam:archive:归档方案的替代选择。若你的业务更看重"移除原集合、归入归档集合"的形态,可参考 archive.md;两者的安装、显式删除(archiveAsyncvssoftRemoveAsync)、恢复(restoreAsyncvsrecoverAsync)接口几乎一一对应,便于在两种方案间切换;jam:offline:离线能力包在其数据同步与对账逻辑中,明确假设应用的删除机制是归档或软删除二者之一。若采用软删除方案,offline 包默认按{ deleted: false }过滤待保留数据;若你自定义了软删除标记字段名,则需要在 offline 包的filter中同步调整。详见 offline.md 中的说明。
小结
jam:soft-delete以极低的接入成本(meteor add jam:soft-delete即可)为 Meteor 应用提供完整的软删除能力:默认覆盖removeAsync、自动注入查询过滤、提供显式的softRemoveAsync与恢复用的recoverAsync,并通过deleted、deletedAt、autoFilter、overrideRemove、exclude五个全局配置项兼顾灵活性。其同构特性与 Meteor 2.8.1+ 的*Async方法族深度绑定,是希望在保留数据的同时获得"删除可撤销"能力的 Meteor 应用的轻量级选择。
- 后端
- 前端
- 开发工具
- 移动开发
【免费下载链接】meteor
Meteor, the JavaScript App Platform
相关推荐
探索数据伪造的艺术:@ngneat/falso
探索数据伪造的艺术:@ngneat/falso 引言:为什么我们需要伪造数据? 在现代软件开发中,测试数据生成是一个不可或缺的环节。无论是单元测试、集成测试还是
数据库时序数据库物联网大数据实时分析云原生AWS CLI 删除 API Gateway REST API 实战指南:`delete-rest-api` 命令的用法、原理与安全删除流程
AWS CLI 删除 API Gateway REST API 实战指南: delete rest api 命令的用法、原理与安全删除流程 导读 本文以 aws
开发工具云原生运维aws-cli 实战指南:使用 `aws autoscaling delete-launch-configuration` 安全删除 EC2 Auto Scaling 启动配置
aws cli 实战指南:使用 aws autoscaling delete launch configuration 安全删除 EC2 Auto Scalin
开发工具云原生运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考