Mongoose中用findByIdAndUpdate实现PATCH多字段更新及请求无响应问题
问题解答
1 PATCH与PUT的误区澄清
首先纠正理解偏差:PATCH 并没有限制只能更新单个字段,它的定位是部分更新,只要你不是要替换整个用户文档,不管更新1个还是N个字段都可以用PATCH。PUT的定位是全量替换,要求请求端上传完整的文档内容直接覆盖原有数据,和更新字段数量没有关系。
2 多字段更新的实现
findByIdAndUpdate的第二个参数就是更新规则对象,你要更新几个字段就往里面加几个键值对即可,比如同时更新login和email的话直接传{login: '新用户名', email: '新邮箱'}就可以。
你自己写的手动判断req.body字段拼接updates对象的写法是完全可用的,还可以进一步简化成白名单过滤写法,避免非法字段被更新:
// 只允许更新指定的三个字段,自动过滤其他字段 const allowedUpdates = ['login', 'email', 'registrationDate'] const updates = Object.fromEntries( Object.entries(req.body).filter(([key]) => allowedUpdates.includes(key)) )
3 请求挂起的问题解决
你遇到的请求一直不结束的问题,原因非常简单:你的接口逻辑里没有给客户端返回任何响应。HTTP协议要求每个请求都必须对应一个响应,你只在控制台打印了日志,没有调用res.json()、res.send()这类方法返回响应,客户端就会一直等待直到超时。
修正后的完整代码如下:
router.patch('/:id', async (req, res) => { const id = req.params.id; const allowedUpdates = ['login', 'email', 'registrationDate'] const updates = Object.fromEntries( Object.entries(req.body).filter(([key]) => allowedUpdates.includes(key)) ) // 第三个参数{new: true}表示返回更新后的文档,runValidators表示触发schema的校验规则 User.findByIdAndUpdate(id, updates, { new: true, runValidators: true }, function (err, updatedUser) { if (err){ console.log(err) // 返回错误响应 return res.status(500).json({message: '更新失败', error: err}) } if (!updatedUser) { // 没找到对应用户的情况 return res.status(404).json({message: '用户不存在'}) } // 返回成功响应 res.status(200).json({message: '更新成功', data: updatedUser}) }); });
内容的提问来源于stack exchange,提问作者sunny
相关产品推荐
相关产品推荐

