You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 00:10:57