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

Mongoose更新数组中disabledBy对象时验证失败的问题求助

问题描述

在Mongoose中定义了Purchase模型,其中包含payments对象数组,尝试为数组内的disabledBy对象设置数据时,Mongoose始终提示未获取到该对象的相关信息。

模型结构

payments: [{
    createdAt: {
        type: String,
        required:true
    },
    paymentNumber: {
        type: Number,
        default:0
    },
    previousBalance:{
        type: Number,
        required: [true, 'El Saldo anterior es obligatorio'],
        default:0
    },
    paymentAmount:{
        type: Number,
        required: [true, 'La Cantidad del Pago(Abono) es obligatorio'],
        default:0
    },
    outstandingBalance:{
        type: Number,
        required: [true, 'El Saldo pendiente es obligatorio'],
        default:0
    },
    createdBy:{
        uid : { type: String, required: true },
        username:{ type: String, required: true }
    },
    comments: {
        type: String,
        maxlength:300,
    },
    status: {
        type: Boolean, 
        default: true
    },
    disabledBy:{ // 尝试更新的对象
        uid:{
            type: String,
            required:true
        },
        username:{
            type: String,
            required:true
        },
        date:{
            type: Date,
            default: Date.now
        },
        comments: {
            type: String,
            maxlength:300,
            required: [true, 'El Comentario es obligatorio']
        }
    }
}],

Express 更新代码

const payment = await Purchase.updateOne( 
    { _id: id, 'payments._id': body.paymentId },
    {
        $set: {
            'payments.$.status': false,
            'payments.$.disabledBy': {
                uid: req.user._id,
                username: req.user.username,   
                comments: body.comments
            }
        }
    },{ new: true });

问题现象与错误信息

更新payments的status属性可正常执行,但更新disabledBy时失败,Mongoose返回错误:

error Purchase validation failed: payments.0.disabledBy.comments: El Comentario es obligatorio, payments.0.disabledBy.username: Path disabledBy.username is required., payments.0.disabledBy.uid: Path disabledBy.uid is required.

尽管传入的disabledBy数据正确,但始终触发上述验证错误,请问如何正确设置该对象的数据?

解决方案

原因分析

Mongoose默认会对整个文档做验证,而非仅更新部分。当更新数组元素时,它会检查数组内所有元素的验证规则,若原数组中存在未初始化disabledBy的元素(比如新增payment时未设置该字段),就会触发必填项验证失败。另外,嵌套对象的更新场景下,默认验证逻辑可能误判传入数据的合规性。

解决办法

1. 仅验证更新字段

在updateOne的选项中添加runValidators: true和context: 'query',让Mongoose只验证你要更新的字段,而非整个文档:

const payment = await Purchase.updateOne( 
    { _id: id, 'payments._id': body.paymentId },
    {
        $set: {
            'payments.$.status': false,
            'payments.$.disabledBy': {
                uid: req.user._id,
                username: req.user.username,   
                comments: body.comments
            }
        }
    },
    { 
        new: true,
        runValidators: true,
        context: 'query' 
    });
  • runValidators: true:启用更新操作的验证逻辑
  • context: 'query':指定验证范围为查询中的更新字段

2. 把disabledBy设为可选字段

如果业务允许payment创建时不设置disabledBy,可修改模型定义,将disabledBy标记为可选:

disabledBy:{
    type: {
        uid:{
            type: String,
            required:true
        },
        username:{
            type: String,
            required:true
        },
        date:{
            type: Date,
            default: Date.now
        },
        comments: {
            type: String,
            maxlength:300,
            required: [true, 'El Comentario es obligatorio']
        }
    },
    required: false // 设置为可选字段
}

这样只有当你主动设置disabledBy时,才会验证其内部字段的必填性,未设置时不会触发错误。

3. 逐个更新disabledBy的内部字段

避免直接替换整个disabledBy对象,而是单独更新每个内部字段,让验证逻辑更精准:

const payment = await Purchase.updateOne( 
    { _id: id, 'payments._id': body.paymentId },
    {
        $set: {
            'payments.$.status': false,
            'payments.$.disabledBy.uid': req.user._id,
            'payments.$.disabledBy.username': req.user.username,   
            'payments.$.disabledBy.comments': body.comments
            // date字段会自动使用默认值,无需手动传入
        }
    },
    { new: true, runValidators: true });

该方式适用于原payment已存在disabledBy对象(或已初始化空对象)的场景,仅更新需要修改的字段,避免触发不必要的验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:54:36