公司动态
meteor-collection-hooks实战:软删除deletedAt模式完整实现
meteor-collection-hooks实战软删除deletedAt模式完整实现【免费下载链接】meteor-collection-hooksMeteor Collection Hooks项目地址: https://gitcode.com/gh_mirrors/me/meteor-collection-hooks在 Meteor 开发中软删除Soft Delete是一种常见且实用的数据管理策略不真正从数据库中移除文档而是通过标记例如deletedAt字段将数据隐藏起来便于日后审计、恢复或数据分析。而 meteor-collection-hooks 正是实现这一模式的利器——它为Mongo.Collection扩展了before/after钩子覆盖insert、update、remove、upsert、find、findOne全操作。本文带你用最少的代码快速实现一套完整的 deletedAt 软删除方案。为什么软删除要用 meteor-collection-hooks传统的硬删除remove()一旦执行数据就彻底消失误删无法挽回。软删除则只需给文档打上deletedAt时间戳标记。但难点在于所有查询都要自动过滤已删除的数据否则软删除就形同虚设。如果手动在每个find里加过滤条件代码会非常啰嗦且容易遗漏。而 meteor-collection-hooks 的before.find/before.findOne/before.remove钩子可以在数据操作发生前自动改写查询条件一次注册、全局生效。这正是它作为 Meteor Collection Hooks 包的核心价值。第一步安装 meteor-collection-hooks在项目根目录执行meteor add matb33:collection-hooks该包支持 Meteor 2.16 与 Meteor 3.x并原生支持异步钩子async hooks安装后即可使用。整个包的封装逻辑可以在 packages/meteor-collection-hooks/ 目录下找到例如 remove.js、find.js。第二步用 before.remove 把删除变成打标记软删除的核心在于拦截remove操作。我们在before.remove钩子中返回false阻止真正删除同时用direct.update绕过钩子的原生方法给文档写入deletedAt时间戳import { Mongo } from meteor/mongo; const Posts new Mongo.Collection(posts); Posts.before.remove(function (userId, doc) { // 阻止硬删除改为写入 deletedAt 标记 Posts.direct.update(doc._id, { $set: { deletedAt: new Date() } }); return false; // 返回 false 阻止后续的 remove 执行 });关键点说明return false所有before钩子返回false都会中止底层操作这也是 remove.js 中约定的行为。使用direct.update而非updatedirect系列方法会绕过所有钩子避免更新时又触发钩子的循环调用。类似地insert、update、remove等都有对应的direct版本。第三步用 before.find 自动过滤已删除数据仅仅打标记还不够查询时必须自动排除带deletedAt的文档。通过before.find钩子我们可以在查询执行前给 selector 追加过滤条件Posts.before.find(function (userId, selector, options) { selector.deletedAt { $exists: false }; // 只查未删除的 }); Posts.before.findOne(function (userId, selector, options) { selector.deletedAt { $exists: false }; });这样项目中所有Posts.find(...)、Posts.findOneAsync(...)都会自动带上软删除过滤无需改动任何业务代码。参考实现见 find.js 与 findone.js。小贴士Meteor 3 中before.find钩子必须是同步函数因为find()需要同步返回游标而before.findOne则支持 async。异步钩子支持范围详见 README.md。第四步恢复与彻底删除软删除的优势在于可恢复。需要恢复数据时清除deletedAt标记即可Posts.direct.update({ _id: postId }, { $unset: { deletedAt: } });如果确需物理删除使用direct.remove绕过所有钩子Posts.direct.remove({ _id: postId }); // 真正的硬删除进阶钩子嵌套时的注意事项当update、remove等操作内部执行find时find钩子也会被触发。如果业务中存在查询已删除数据的需求如后台回收站可以临时用direct绕过或者结合CollectionHooks.directEnv在嵌套回调中恢复钩子环境详见 utils.js。官方测试用例 tests-app/find_after_hooks.test.js 中还展示了before.find与after.update的交互边界值得参考。总结通过 meteor-collection-hooks我们用不到 20 行代码就实现了完整的软删除方案操作钩子行为删除before.remove写入deletedAt并阻止硬删除查询before.find/before.findOne自动过滤已删除文档恢复direct.update清除deletedAt标记彻底删除direct.remove绕过钩子物理删除这套 deletedAt 模式不仅代码量小、入侵性低还能避免误删风险非常适合中小型 Meteor 项目。配合 async 钩子与 Meteor 3 兼容性meteor-collection-hooks 可以放心地成为你项目的数据层基础设施。赶紧在你的 Meteor 项目中试试吧【免费下载链接】meteor-collection-hooksMeteor Collection Hooks项目地址: https://gitcode.com/gh_mirrors/me/meteor-collection-hooks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考