MongoDB更新失败:无法将MySQL查询结果推入developers数组
问题分析与修复方案
你的代码存在几个关键问题,导致developers数组始终无法被正确更新,我来逐一拆解说明:
1. MySQL连接被提前关闭
你把mySQLdb.end()放在了mySQLdb.query()的回调函数外部,这会导致MySQL查询还没执行完成,连接就被强制关闭了。虽然你提到console.log(results)能看到数据,但这只是偶然情况,这种写法本身存在逻辑漏洞,必须把关闭连接的操作移到查询回调的最后环节。
2. MongoDB更新操作未处理异步逻辑
Project.update()是异步操作,但你的代码既没有等待它执行完成,也没有添加错误处理逻辑。而且在Mongoose中,更推荐使用语义更明确的updateOne()或findByIdAndUpdate()方法,同时需要通过回调或await来确保更新操作真正生效。另外,你原代码里的Project.update()没有传入回调,即使更新失败(比如找不到对应Project文档),你也完全看不到错误信息。
3. 路由的async声明未被充分利用
你的路由函数标记了async,但内部却混用了回调式的MySQL查询,导致代码逻辑嵌套混乱,也无法借助await简化异步流程。
修正后的代码
我将代码调整为基于async/await的写法,同时修复了SQL注入风险、异步逻辑问题:
router.post('/saveDeveloper', async (req, res) => { try { const userList = req.body.attuid; // 拆分用户ID并去除空格 const cleanedUserIds = userList.split(',').map(attuid => attuid.trim()); // 建立MySQL连接 mySQLdb.connect(); // 使用参数化查询避免SQL注入风险 const sql = `SELECT userid, fullName FROM users WHERE userid IN (?)`; const [results] = await mySQLdb.query(sql, [cleanedUserIds]); console.log('查询到的开发者数据:', results); // 用findByIdAndUpdate确保精准更新并获取结果 const updatedProject = await Project.findByIdAndUpdate( req.body.projectID, { "$push": { "developers": { "$each": results } } }, { new: true } // 可选:返回更新后的完整文档 ); if (!updatedProject) { return res.status(404).json({ message: '未找到对应项目文档' }); } // 所有操作完成后再关闭MySQL连接 mySQLdb.end(); res.json({ message: '开发者列表更新成功', data: results }); } catch (err) { console.error('操作出错:', err); // 出错时也要确保关闭连接 mySQLdb.end(); res.status(500).json({ error: err.message }); } });
额外重要提醒
- SQL注入风险:你原代码直接将用户输入拼接进SQL语句,这是非常危险的操作,极易引发SQL注入攻击,上面的代码已经改用参数化查询修复了这个问题。
- 错误处理:新增的
try/catch可以捕获所有异步操作的错误,避免服务器崩溃,同时给客户端返回清晰的错误信息。 - Mongoose版本兼容:如果你的Mongoose版本较旧,
findByIdAndUpdate的语法可能略有差异,但$push搭配$each的数组更新语法是MongoDB原生支持的,不会有问题。
内容的提问来源于stack exchange,提问作者user752746
相关产品推荐
相关产品推荐

