为何mongoose-findorcreate插件会批量创建无效Follower文档?
排查MERN应用Follower模块批量创建无效文档问题
以下是针对你遇到的Follower模块批量生成无效(userId不存在)文档问题的具体排查方向和解决方案:
1. 检查mongoose-findorcreate的调用逻辑
- 确认调用
findOrCreate时的查询条件是否精准:如果传入的userId为空、未定义或取错了变量,插件会因为找不到匹配文档而反复创建新的无效记录。要确保你是从正确的上下文(比如当前登录用户ID、被关注用户ID)获取参数,而非误传了空值。 - 排查是否存在重复调用:比如在循环、异步回调或事件监听中多次触发Follower的创建逻辑,比如前端按钮未做防抖、后端路由被重复请求,导致
findOrCreate被执行6-8次。
2. 异步流程控制校验
- 检查Follower相关的服务/控制器代码,确认异步操作是否正确处理:比如使用
async/await时是否遗漏了await,导致代码并行执行,多次触发创建;或者Promise链式调用出错,导致创建逻辑被重复执行。 - 举例:如果在创建Following后,创建Follower的逻辑被放在了未正确控制的回调中,可能会因为异步触发多次执行。
3. 给Schema添加数据校验
在Follower Schema中添加强制校验,避免无效数据存入:
const FollowerSchema = new mongoose.Schema({ userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true, // 自定义校验:确保userId对应的用户存在 validate: { validator: async function(userId) { const userExists = await mongoose.model('User').exists({ _id: userId }); return userExists; }, message: '该userId对应的用户不存在' } }, followerId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true } }); // 加载findorcreate插件 FollowerSchema.plugin(findOrCreate);
开启mongoose的验证逻辑,确保创建时触发校验:
// 创建时添加runValidators选项 await Follower.findOrCreate( { userId: targetUserId, followerId: currentUserId }, { runValidators: true } );
4. 调试与日志排查
- 在Follower创建的代码位置添加日志,打印每次调用时的
userId和followerId参数,确认是否存在多次调用且参数异常的情况:console.log('创建Follower,参数:', { userId, followerId }); - 查看数据库中无效文档的创建时间,如果是同一时间批量生成,说明是单次请求内多次执行创建逻辑;如果时间分散,可能是前端多次触发请求。
5. 替换插件验证逻辑
暂时移除mongoose-findorcreate,改用手动的查询+创建逻辑,排查是否是插件使用问题:
async function createFollower(userId, followerId) { let follower = await Follower.findOne({ userId, followerId }); if (!follower) { // 先校验用户是否存在 const userExists = await mongoose.model('User').exists({ _id: userId }); if (!userExists) { throw new Error('用户不存在'); } follower = await Follower.create({ userId, followerId }); } return follower; }
内容的提问来源于stack exchange,提问作者Frank Uhal
相关产品推荐
相关产品推荐

