Nodejs mongoose操作mongodb报错 _id拒绝

发布于 1周前 作者 songsunli 来自 nodejs/Nestjs

Nodejs mongoose操作mongodb报错 _id拒绝

使用nodejs+mongoose更新用户账号时报_id主键拒绝 enter image description here

exports.updateAccount = function(req, res, next) {
var proxy = new EventProxy();

var render = function(data) {
    res.send(data);
};

proxy.assign('updateAccount', render);

var where = {};

var userId = req.param('userid')
    , account = req.param('account')
    , password = req.param('password2')
    , username = req.param('username');

where = {'_id': userId, 'password': password};
Account.findOne(where, function(err, account) {
    if (err)
        return next(err);

    var result;
    if (account != null) {

        account.account = account;
        account.password = password;
        account.username = username;
        console.log(account+'dd');
        account.update(function(err) {
            if (err)
                return next(err);
        });
        result = {'success': true};
    } else {
        result = {'success': false};
    }
    proxy.trigger('updateAccount', result);
});

}


7 回复

针对你提供的问题描述,_id 拒绝的错误通常是因为你在尝试更新文档时,没有正确地处理 _id 字段。Mongoose 在默认情况下会自动管理 _id 字段,因此你不应该手动设置它。

以下是一个改进后的代码示例,修复了这个问题:

const mongoose = require('mongoose');
const Account = mongoose.model('Account'); // 假设你已经定义了Account模型

exports.updateAccount = async function(req, res, next) {
    try {
        const userId = req.params.userid; // 使用req.params而不是req.param
        const account = req.body.account || req.query.account; // 从body或query中获取account
        const password = req.body.password2 || req.query.password2; // 从body或query中获取password
        const username = req.body.username || req.query.username; // 从body或query中获取username

        // 查找并更新用户信息
        const result = await Account.findByIdAndUpdate(
            userId,
            { account, password, username }, // 更新字段
            { new: true } // 返回更新后的文档
        );

        if (!result) {
            return res.status(404).send({ success: false, message: "User not found" });
        }

        res.send({ success: true, user: result });

    } catch (error) {
        next(error); // 将错误传递给全局错误处理中间件
    }
};

解释:

  1. 参数获取:使用 req.params 获取 userid,使用 req.bodyreq.query 获取其他参数。
  2. 更新方法:使用 findByIdAndUpdate 方法,这样可以避免手动构建查询条件,并且可以一次性更新多个字段。
  3. { new: true }:确保返回的是更新后的文档,而不是更新前的文档。
  4. 错误处理:使用 try...catch 结构来捕获并处理可能发生的错误,并通过 next(error) 将错误传递给全局错误处理中间件。

这样可以避免直接处理 _id 字段导致的错误,并简化了代码逻辑。


说明下你的代码很严重的问题,你在使用account.accout = accout的时候就没有意识到accout对应的是哪个__account__吗?你这样会出现对象链的循环递归引用嵌套!

后来调试知道了这个问题 但是不让更新还是存在 纠结了好久了

好像 update是类对象的方法吧 实例对象用save方法

我调试下看能行不 呵呵

确实实例使用save方法

根据你的描述,问题在于你在更新用户账号时错误地设置了account.account。以下是修改后的代码:

exports.updateAccount = function(req, res, next) {
    var proxy = new EventProxy();

    var render = function(data) {
        res.send(data);
    };

    proxy.assign('updateAccount', render);

    var where = {};

    var userId = req.param('userid'),
        account = req.param('account'),
        password = req.param('password2'),
        username = req.param('username');

    where = {'_id': userId, 'password': password};
    Account.findOne(where, function(err, accountDoc) {
        if (err)
            return next(err);

        var result;
        if (accountDoc != null) {
            accountDoc.account = account;
            accountDoc.password = password;
            accountDoc.username = username;

            accountDoc.save(function(err) {
                if (err)
                    return next(err);

                result = {'success': true};
            });
        } else {
            result = {'success': false};
        }
        proxy.trigger('updateAccount', result);
    });
};

修改点:

  1. account 改为 accountDoc 以避免与变量名冲突。
  2. 使用 save 方法来保存更改,而不是 update 方法。
  3. save 回调函数中设置 result

这样应该可以解决 _id 主键拒绝的问题。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!