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

Node.js+MongoDB API:PUT请求返回成功但未更新字段

问题:PUT请求返回成功但MongoDB字段未实际更新

我正在开发一个用于检索和更新MongoDB数据的API,目前GET请求可以正常获取数据,但执行PUT请求时,虽然返回了Field replaced successfully,但通过GET验证发现数据库中的字段并未发生变化。API要求请求携带以下参数:

  • key:必填的请求授权参数
  • id:指定要检索或更新的字段

数据库结构示例:

{
    "userId": {
        "customs": [
            "Sword",
            "Spear"
        ],
        "morphs": [
            "Knight",
            "Jester"
        ]
    }
}

相关代码如下:

var Express = require("express");
var MongoClient = require("mongodb").MongoClient;
var cors = require("cors")

const multer = require("multer")

var app = Express()
app.use(cors());
app.use(Express.json());

var connection_string = "connection-string"
var validKey = "60YGrhgU6MEz9E1UZmaMLFlAvKTbYGLGof3PRTmvAmxYWXQeeXIbjPiFhUUVaWqBc"

var databaseName = "data"
var database;

app.listen(5038, () => {
    MongoClient.connect(connection_string, (error, client) => {
        database = client.db(databaseName);
        console.log("Connected to MongoDB")
    });
})

app.get('/api/lsbg', (request, response) => {
    const key = request.query.key;
    const id = request.query.id;

    if (key !== validKey) {
        response.status(401).send({ "code": 401, "error": "Invalid key" })
    } else {
        if (!id) {
            database.collection("giver").find({}).forEach(doc => {
                response.send(doc)
            })
        } else if (id === 0) {
            database.collection("giver").find({}).forEach(doc => {
                response.send(doc)
            })
        } else {
            database.collection('giver').findOne({}, (error, result) => {
                if (error) {
                    response.status(404).json({ "code": 500, error: 'Internal server error' });
                } else if (result && result.hasOwnProperty(id)) {
                    response.json(result[id]);
                } else {
                    response.status(404).json({ "code": 404, error: `Could not find data of id ${id}` });
                }
            });
        }
    }
})

app.put('/api/lsbg', (req, res) => {
    const id = req.params.id;
    const updatedValue = req.body; 

    const updateQuery = { [id]: updatedValue };

    database.collection('giver').updateOne(
        {},
        { $set: updateQuery },
        (error, result) => {
            if (error) {
                res.status(500).json({ error: 'Internal server error' });
            } else {
                res.json({ message: 'Field replaced successfully' });
            }
        }
    )
});

问题根源分析

  1. id参数获取错误:PUT接口中尝试从req.params.id获取id,但路由/api/lsbg并未定义路径参数(如/api/lsbg/:id),根据需求id是作为查询参数传递的(与GET接口一致),因此实际id值为undefined,导致$set的键无效,没有更新任何字段。
  2. 缺少key授权验证:PUT接口未校验请求中的key参数,既存在安全隐患,也不符合API参数要求。
  3. 更新结果未校验:无论updateOne是否实际修改了文档,都会返回成功提示,无法区分“执行成功但无文档被修改”和“真正更新成功”的情况。

修复后的PUT接口代码

app.put('/api/lsbg', (req, res) => {
    const key = req.query.key;
    const id = req.query.id;
    const updatedValue = req.body; 

    // 验证key合法性
    if (key !== validKey) {
        return res.status(401).send({ "code": 401, "error": "Invalid key" });
    }

    // 验证id是否存在
    if (!id) {
        return res.status(400).json({ "code": 400, error: "id parameter is required" });
    }

    const updateQuery = { [id]: updatedValue };

    database.collection('giver').updateOne(
        {}, // 建议添加明确文档匹配条件(如{ _id: xxx }),避免误修改集合中其他文档
        { $set: updateQuery },
        (error, result) => {
            if (error) {
                return res.status(500).json({ "code": 500, error: 'Internal server error' });
            }
            // 检查是否有文档被实际修改
            if (result.modifiedCount === 0) {
                return res.status(404).json({ "code": 404, error: `Could not find field with id ${id} or no changes made` });
            }
            res.json({ message: 'Field replaced successfully' });
        }
    )
});

额外优化建议

  • 修正GET接口中find({}).forEach(doc => response.send(doc))的问题:response.send只能调用一次,后续调用会报错,建议用toArray()统一返回所有文档:
    database.collection("giver").find({}).toArray((err, docs) => {
        if (err) return res.status(500).json({ error: 'Internal server error' });
        res.send(docs);
    });
    
  • 在updateOne的查询条件中添加明确的文档匹配规则(如根据_id或唯一字段),避免误修改集合中的其他文档。

内容的提问来源于stack exchange,提问作者kesect

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:55:56