FindOneAndUpdate更新变量成功但MongoDB数据库未同步问题
问题描述
我开发一款应用,规则为未完成培训的用户需完成培训,培训完成后User集合的trainingComplete字段需从false改为true。当前代码中,console.log(updatedUser)显示该字段已变为true,但MongoDB Compass中实际数据库无变化。我尝试过使用updateOne、.save(),均未解决问题。
相关代码
后端(Mongoose + Express)
const userSchema = new mongoose.Schema({ email: String, username: String, password: String, trainingComplete: { type: Boolean, default: false, }, topScore: { type: Number, default: 0, }, }); const User = mongoose.model("User", userSchema); app.put("/users/:username", async (req, res) => { try { let { username } = req.params; console.log(username); let updatedUser = await User.findOneAndUpdate( { username: username }, { $set: { trainingComplete: true } }, // Update trainingComplete to true { new: true }, ); //await updatedUser.save(); console.log("UpdatedUser:", updatedUser); if (!updatedUser) { return res.status(404).json({ message: "User not found" }); } res.json({ message: "Training status updated successfully", updatedUser }); console.log("Updated Successfully"); } catch (error) { console.error("Error updating training status: ", error); res.status(500).json({ error: "Internal Server Error" }); } });
前端(React Native)
const handleConfirm = async () => { try { let userRating = Math.max(selectedRating); console.log("UserRating", userRating); const response = await fetch(`http://192.168.0.189:3000/patients/${patientID}`); if (response.ok) { const { patientData, maxNumber } = await response.json(); console.log("Patient Data:", patientData); console.log("Maximum Number:", maxNumber); if (userRating === maxNumber) { console.log("Correct"); setRatingCorrect(true); const username = await AsyncStorage.getItem("username"); console.log("Username", username); // Update the trainingComplete field for the logged-in user await fetch(`http://192.168.0.189:3000/users/${username}`, { method: "put", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ trainingComplete: true }), }); navigation.navigate("Profile"); } else { console.log("Incorrect"); setRatingCorrect(false); } setConfirmPressed(true); } else { console.error("Failed to fetch patient data:", response.statusText); } } catch (error) { console.error("Error updating lesion_GS:", error); } };
解决方案
1. 验证数据库连接与目标库一致性
先确认后端代码连接的MongoDB实例,和你在Compass中查看的是同一个数据库(比如是否误连了测试库、内存库,或者远程实例)。可以在后端启动时打印数据库连接信息,确认连接的DB名称和地址。
2. 检查查询条件是否精准匹配
MongoDB默认对字符串查询区分大小写,如果前端传入的username和数据库中存储的大小写不一致(比如前端传"Alice",数据库里是"alice"),会导致更新操作匹配不到文档。你可以在后端接口中,先查询一次用户,确认是否存在:
// 在update前先查询用户 const existingUser = await User.findOne({ username: username }); console.log("查询到的用户:", existingUser); // 如果是null,说明用户名不匹配
3. 改用updateOne并查看更新统计
findOneAndUpdate的new: true只会返回更新后的文档,但无法直观看到数据库实际修改了多少条数据。改用updateOne并检查返回的结果对象:
app.put("/users/:username", async (req, res) => { try { const { username } = req.params; const updateResult = await User.updateOne( { username: username }, { $set: { trainingComplete: true } } ); console.log("更新统计:", updateResult); // nModified为0说明没找到匹配的文档,或者字段已经是true if (updateResult.nModified === 0) { const existingUser = await User.findOne({ username: username }); if (!existingUser) { return res.status(404).json({ message: "用户不存在" }); } return res.status(200).json({ message: "无需更新,培训状态已完成", updatedUser: existingUser }); } // 查询最新数据返回给前端 const updatedUser = await User.findOne({ username: username }); res.json({ message: "培训状态更新成功", updatedUser }); } catch (error) { console.error("更新失败:", error); res.status(500).json({ error: "服务器内部错误" }); } });
4. 验证前端传入的用户名正确性
在前端handleConfirm中,确认AsyncStorage.getItem("username")拿到的用户名没有空格、拼写错误,或者为空。可以在fetch前多打印一层验证:
const username = await AsyncStorage.getItem("username"); console.log("待更新的用户名:", username.trim()); // 去掉可能的空格 if (!username) { console.error("未获取到当前用户名"); return; }
5. 排除Mongoose缓存干扰
Mongoose默认会缓存查询结果,可能导致你看到的updatedUser是缓存数据,而非数据库实际值。可以在查询时禁用缓存,或者更新后重新查询一次:
// 更新后重新查询数据库 const updatedUser = await User.findOne({ username: username }, null, { cache: false });
内容的提问来源于stack exchange,提问作者Ela
相关产品推荐
相关产品推荐

