Express.js中使用MongoDB find()校验用户职位申请状态失效问题排查
问题根源与修复方案
你的代码核心问题在于没有等待异步查询完成:Mongoose的find().count()是异步操作,会返回一个Promise对象,而你直接把这个Promise赋值给了count变量,并没有等待它解析出实际的数字结果。所以count > 0这个判断永远为false(因为Promise对象和0比较会被转为NaN,NaN > 0是false),导致每次请求都会直接进入else分支创建新申请。
修复步骤1:添加await获取实际计数
把计数查询改为异步等待,同时注意Mongoose 6.x版本开始count()方法已被弃用,更推荐使用countDocuments():
router.post('/', async(req,res)=>{ // 等待查询完成,获取实际计数 const count = await Apply.countDocuments({user: req.body.user, job: req.body.job}); if(count > 0){ return res.status(400).send('already applied'); } else{ let apply = new Apply({ job : req.body.job, user : req.body.user }); apply = await apply.save(); if(!apply) return res.status(400).send('cannot apply'); res.send(apply); } })
优化建议:用findOne()提升性能
其实你不需要统计所有重复的申请,只要确认是否存在至少一条即可,用findOne()会更高效——它找到匹配的文档后就会停止查询,不需要遍历整个集合:
router.post('/', async(req,res)=>{ const existingApply = await Apply.findOne({user: req.body.user, job: req.body.job}); if(existingApply){ return res.status(400).send('already applied'); } // 没有重复则创建新申请 const apply = new Apply({ job : req.body.job, user : req.body.user }); const savedApply = await apply.save(); if(!savedApply) return res.status(400).send('cannot apply'); res.send(savedApply); })
额外提示:添加唯一索引
为了从数据库层面杜绝重复申请,你可以给Apply模型的user和job字段添加复合唯一索引,这样即使代码层面出现疏漏,数据库也会抛出错误阻止重复数据插入:
// 在你的Apply模型定义中添加 ApplySchema.index({ user: 1, job: 1 }, { unique: true });
这样当重复插入时,save()会抛出DuplicateKey错误,你可以在代码中捕获这个错误并返回友好提示:
router.post('/', async(req,res)=>{ try { const existingApply = await Apply.findOne({user: req.body.user, job: req.body.job}); if(existingApply){ return res.status(400).send('already applied'); } const apply = new Apply({ job : req.body.job, user : req.body.user }); const savedApply = await apply.save(); res.send(savedApply); } catch (err) { // 捕获唯一索引冲突错误 if(err.code === 11000){ return res.status(400).send('already applied'); } res.status(500).send('server error'); } })
内容的提问来源于stack exchange,提问作者singledime
相关产品推荐
相关产品推荐

