如何在使用Mongoose操作MongoDB的FeathersJS项目中实现软删除
FeathersJS 配合 Mongoose 实现软删除的 Hooks 开发方案
1. 调整 Mongoose 数据模型
首先在需要软删除的业务模型中新增软删除标记字段,示例如下:
const mongoose = require('mongoose') const yourSchema = new mongoose.Schema({ // 原有业务字段保持不变 isDeleted: { type: Boolean, default: false, index: true }, deletedAt: { type: Date, default: null }, // 按需新增:记录删除操作的用户ID deletedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', default: null } }) module.exports = mongoose.model('YourModel', yourSchema)
提示:给isDeleted加索引可以提升过滤软删除数据的查询效率
2. 编写软删除核心钩子
该钩子会拦截默认的删除请求,将物理删除改为更新软删除标记,无需实际删除数据库数据:
// 软删除前置钩子,挂载到服务的 before.remove 钩子数组中 const softDeleteHook = async (context) => { const { id, service, params } = context // 支持强制物理删除:如果请求传了 forceDelete=true 则跳过软删除逻辑 if (params.query?.forceDelete) { delete params.query.forceDelete return context } // 执行更新操作,标记数据为已删除 await service.patch(id, { isDeleted: true, deletedAt: new Date(), deletedBy: params.user?._id || null }, params) // 给 context.result 赋值后,Feathers 会跳过默认的 remove 执行逻辑 context.result = await service.get(id, params) return context }
3. 编写软删除数据过滤钩子
该钩子会自动拦截查询请求,默认过滤掉已软删除的数据,避免业务侧每次手动加条件:
// 软删除过滤前置钩子,挂载到服务的 before.find、before.get 钩子数组中 const filterSoftDeletedHook = async (context) => { const { params } = context if (!params.query) params.query = {} // 支持查询已删除数据:如果请求传了 includeDeleted=true 则不过滤软删除数据 if (!params.query.includeDeleted) { params.query.isDeleted = { $ne: true } } else { delete params.query.includeDeleted } return context }
4. 注册钩子到对应服务
在服务的hooks配置文件中挂载上述两个钩子即可生效,示例如下:
// your-service.hooks.js const { softDeleteHook, filterSoftDeletedHook } = require('./hooks/soft-delete.hooks') module.exports = { before: { all: [], find: [filterSoftDeletedHook], get: [filterSoftDeletedHook], create: [], update: [], patch: [], remove: [softDeleteHook] }, // 其余after、error钩子保留原有业务逻辑即可 after: {}, error: {} }
可选扩展
- 数据恢复功能:单独写一个恢复接口,或者在patch逻辑中增加判断,把
isDeleted改为false、deletedAt设为null即可恢复已软删数据 - 关联查询适配:如果用到populate关联查询,关联的模型也做了软删除的话,需要在populate的match参数中也加上
isDeleted: { $ne: true }的过滤条件
内容的提问来源于stack exchange,提问作者Sibtain Wani
相关产品推荐
相关产品推荐

