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

Mongoose更新异常:User集合部分字段未成功写入

问题:Mongoose更新User集合bunches数组时name字段无法写入

定义的Mongoose Schema

const userSchema = new mongoose.Schema({
name: {
    type: String,
    required: true
},
email: {
    type: String,
    required: true,
    unique: true,
},
password: {
    type: String,
    required: true,
},
avatar: {
    type: String
},
date: {
    type: Date,
    default: Date.now
},
bunches: [{
    bunch: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'bunch'
    },
    bunchName: {
        name: String,
    },
    bunchId: {
        type: String
    }
}]
 });


const bunchSchema = new mongoose.Schema({
bunchId: {
    type: String,
    required: true,
},
secret: {
    type: String,
    required: true
},
name: {
    type: String
},
tag: {
    type: String
},
description: {
    type: String,
},
wallpaper: {
    type: String
},
date: {
    type: Date,
    default: Date.now
},
users: [{
    user: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'user'
    },
    name: {
        type: String,
    },
    avatar: {
        type: String,
    }
}],
 });

需求

用户创建新Bunch后,需将以下三个字段写入User模型的bunches数组:

  • bunchId
  • Bunch的_id
  • Bunch的name

问题代码

router.post("/create", [middlwares] , async (req, res) => {

const errors = validationResult(req);
if (!errors.isEmpty()) {
    // Then there are some errors
    return res.status(400).json({ errors: errors.array() })
}

const { name, secret } = req.body;
try {

    let user = await User.findOne({ _id: req.user.id });
  
    if (!user) {
        return res.status(400).json({ msg: 'please login' });
    }
    const bunchId = uuidv4();

    const bunch = new Bunch({
        name,
        bunchId,
        secret,
        users: [
            {
                user: req.user.id,
                name: user.name,
                avatar: user.avatar
            }
        ],
    });

    // hash the secret & save the bunch
    const salt = await bcrypt.genSalt(10);
    bunch.secret = await bcrypt.hash(secret, salt);
    await bunch.save();

    let bunchArr = [];
    bunchArr = user.bunches;

    console.log("before", bunchArr);

    let newBunchArr = [...bunchArr, { bunchName: name, bunch: bunch.id, bunchId }];

    console.log("after", newBunchArr);

    await User.findOneAndUpdate({ _id: req.user.id }, { $set: { bunches: newBunchArr } });
    // generate a payload
    const payload = {
        user: {
            id: user.id,
        },
        bunch: {
            id: bunch.id
        }
    };

    jwt.sign(
        payload,
        config.get('jwtSecret'),
        { expiresIn: 360000 },
        (err, token) => {
            if (err) throw err;
            res.json({ token });
        }
    );

} catch (error) {
    console.error(error.message);
    res.status(500).send('server error');
}
 });

遇到的问题

所有尝试中,仅bunch和bunchId字段成功更新至数据库,name字段始终未被写入。
数据库截图


解决方案

问题根源

查看UserSchema的定义,bunches数组里的bunchName是一个嵌套对象:

bunchName: {
    name: String,
}

但你在代码里直接给bunchName赋值为字符串name,而非符合Schema结构的{name: name},Mongoose会因结构不匹配忽略该字段的写入操作。

两种修复方式

方式1:修改代码赋值逻辑

保持Schema不变,添加新bunch到数组时按照Schema结构赋值:

// 替换原newBunchArr定义
let newBunchArr = [...bunchArr, { 
    bunchName: { name: name }, // 改为嵌套对象格式
    bunch: bunch._id, // 建议用bunch._id替代bunch.id,更符合MongoDB规范
    bunchId 
}];

方式2:简化UserSchema中的bunchName定义

如果仅需存储Bunch的name字符串,无需嵌套对象,直接修改Schema:

bunches: [{
    bunch: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'bunch'
    },
    bunchName: String, // 直接定义为String类型
    bunchId: {
        type: String
    }
}]

修改后原代码中的bunchName: name赋值即可正常生效。

额外优化建议

  • 使用$push替代重新赋值整个数组,更高效安全:
    await User.findOneAndUpdate(
        { _id: req.user.id }, 
        { 
            $push: { 
                bunches: { 
                    bunchName: { name: name }, // 或bunchName: name,根据选择的方式调整
                    bunch: bunch._id, 
                    bunchId 
                } 
            } 
        }
    );
    
    无需先查询用户的bunches数组,直接追加元素,减少数据库操作次数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:57:18