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替代重新赋值整个数组,更高效安全:
无需先查询用户的bunches数组,直接追加元素,减少数据库操作次数。await User.findOneAndUpdate( { _id: req.user.id }, { $push: { bunches: { bunchName: { name: name }, // 或bunchName: name,根据选择的方式调整 bunch: bunch._id, bunchId } } } );
内容的提问来源于stack exchange,提问作者Nav
相关产品推荐
相关产品推荐

