MongoDB更新用户数据报错求助:多种方法尝试无效
问题描述
更新MongoDB用户数据时触发报错(错误截图如下),尝试过findOneAndUpdate、updateOne等方法均无效。

相关代码
mainController
updateUser: async (req, res) => { try { const updatedUser = await UserSchema.updateOne({ secret: req.params.secret }, { $set: req.body }); res.status(200).json(updatedUser); } catch (error) { res.status(400).json({ message: error.message }); } },
路由配置
mainRouter.post('/update/:secret', updateUser)
前端React代码
import React, { useState, useEffect } from 'react'; import { Link, useParams, useNavigate } from 'react-router-dom'; import Toolbar from '../components/Toolbar'; import { get, post } from '../helper/helper'; export default function TestPage() { const [current, setCurrent] = useState('') const [index, setIndex] = useState(0); const [allUsers, getAllUsers] = useState([]) const secret = window.localStorage.getItem('secret') const nav = useNavigate() useEffect(() => { async function currentUser() { const resp = get(`user/${secret}`) setCurrent(resp) } currentUser() }, []) useEffect(() => { async function fetchUsers() { const resp = await get('api') getAllUsers(resp) } fetchUsers() }, []) allUsers.filter(user => user.secret !== secret) console.log(index) const currentUser = allUsers[index]; async function postLiked() { const likedObj = { liked: [currentUser] } const likesObj = { likes: [current] } await post(`update/${current.secret}`, likedObj) await post(`update/${currentUser.secret}`, likesObj) } async function postDislike() { const dislikeObj = { disliked: [currentUser] } await post(`update/${current.secret}`, dislikeObj) } return ( <div className='home__page'> <Toolbar /> <div className="home__users"> <div className='single__user'> <img src={currentUser && currentUser.image[0]} alt="" /> <h3>{currentUser && `${currentUser.firstName} ${currentUser.lastName}`}</h3> <h4>{currentUser && currentUser.gender}</h4> <button onClick={() => { setIndex(index + 1); postDislike(); nav(`/${currentUser.secret}`) }}>Dislike</button> <button onClick={() => { setIndex(index + 1); postLiked(); nav(`/${currentUser.secret}`) }}>Like</button> </div> </div> <footer className='footer'> <p>All rights reserved by Cartoon Match organization. To read more about our policy <Link to='/policy'>click here</Link>. </p> </footer> </div> ) }
helper.js代码
export const get = async (url) => { const options = { method: 'GET', headers: { 'Content-type': 'application/json', }, }; const response = await fetch(`http://localhost:4000/${url}`, options); if (response.ok) { const dataFromGetRequest = await response.json(); return dataFromGetRequest; } }; export const post = async (body, url) => { const options = { method: 'POST', headers: { 'Content-type': 'application/json', }, body: JSON.stringify(body), }; const response = await fetch(`http://localhost:4000/${url}`, options); if (response.ok) { const dataFromPostRequest = await response.json(); return dataFromPostRequest; } }; export const put = async (body, url) => { const options = { method: 'PUT', headers: { 'Content-type': 'application/json', }, body: JSON.stringify(body), }; const response = await fetch(`http://localhost:4000/${url}`, options); if (response.ok) { const dataFromPostRequest = await response.json(); return dataFromPostRequest; } };
解决方案
排查后发现几个核心问题,逐一修复即可解决更新失败:
1. 修复helper中post/put方法的参数顺序
当前post、put方法定义是(body, url),但前端调用时传的是(url, body),导致后端接收到的req.body是字符串而非更新对象。调整参数顺序并添加错误处理:
export const post = async (url, body) => { const options = { method: 'POST', headers: { 'Content-type': 'application/json' }, body: JSON.stringify(body), }; const response = await fetch(`http://localhost:4000/${url}`, options); if (response.ok) return await response.json(); throw new Error(`请求失败,状态码:${response.status}`); }; export const put = async (url, body) => { const options = { method: 'PUT', headers: { 'Content-type': 'application/json' }, body: JSON.stringify(body), }; const response = await fetch(`http://localhost:4000/${url}`, options); if (response.ok) return await response.json(); throw new Error(`请求失败,状态码:${response.status}`); };
2. 修复前端get请求未加await的问题
currentUser函数中调用get未加await,导致current存储的是Promise对象,后续current.secret为undefined,后端无法匹配文档:
useEffect(() => { async function currentUser() { const resp = await get(`user/${secret}`); setCurrent(resp); } currentUser(); }, [secret]);
3. 改用$push/$addToSet更新数组字段
用$set会直接覆盖原有数组,正确做法是用$push添加元素,需要去重则用$addToSet:
updateUser: async (req, res) => { try { const updateObj = {}; Object.keys(req.body).forEach(key => { if (Array.isArray(req.body[key])) { updateObj['$push'] = updateObj['$push'] || {}; updateObj['$push'][key] = req.body[key][0]; // 去重替换:updateObj['$addToSet'][key] = req.body[key][0]; } else { updateObj['$set'] = updateObj['$set'] || {}; updateObj['$set'][key] = req.body[key]; } }); const updatedUser = await UserSchema.updateOne( { secret: req.params.secret }, updateObj, { new: true } ); res.status(200).json(updatedUser); } catch (error) { res.status(400).json({ message: error.message }); } },
4. 遵循RESTful规范改用PUT方法
更新资源建议用PUT而非POST,修改路由并调整前端调用:
// 路由配置 mainRouter.put('/update/:secret', updateUser); // 前端postLiked/postDislike中替换post为put await put(`update/${current.secret}`, likedObj); await put(`update/${currentUser.secret}`, likesObj); // postDislike同理
5. 修复用户数组过滤逻辑
原过滤代码未保存结果,导致可能匹配到当前用户自己:
const filteredUsers = allUsers.filter(user => user.secret !== secret); const currentUser = filteredUsers[index];
内容的提问来源于stack exchange,提问作者Paulius
相关产品推荐
相关产品推荐

