Node.js中向MongoDB文档数组追加数据失败,求排查解决
问题描述
我的MongoDB数据结构如下:
[ { "_id": "66076517c835e00d55714b41", "UMKC": { "users": { "professors": [], "students": [], "admins": [] } } }, { "_id": "66076517c835e00d55714b41", "UNT": { "users": { "professors": [], "students": [], "admins": [] } } } ]
我希望根据用户角色向对应数组追加如下格式的数据:
{ "fname": fname, "lname": lname }
我编写了如下Node.js(Express)接口代码尝试更新:
router.post('/register', async (req, res) => { const { fname, lname, email, univName, id, role, password, _id } = req.body; const adminData = { fname, lname, email, id, password } const filter = { _id: new ObjectId(_id) } try { const updateResult = await Users.updateOne({filter}, {$push:{ 'users.admins':{ 'fname':fname, 'lname':lname, 'id':id, 'email':email, 'password':password } }} );console.log(updateResult) } catch (error) { console.log(error) } })
我的Users模型代码如下:
const mongoose = require('mongoose'); const userSchema = new mongoose.Schema({ id: { type: Number, required: true, unique: true }, fname: { type: String, required: true, minlength: 2, maxlength: 50 }, lname: { type: String, required: true, minlength: 2, maxlength: 50 }, email: { type: String, required: true, unique: true, validate: { validator: (email) => /^[\w-\.]+@([\w-]+\.)+[a-zA-Z]{2,4}$/.test(email), message: 'Please enter a valid email address.' } }, password: { type: String, required: true, minlength: 8 } }); const Users = mongoose.model('Users', userSchema); module.exports = Users; // Export the Users model directly
但数据库数据并未更新,我尝试将$push的路径改为'UNT.users.admins'或[${univName}].users.admins也无效,请问我哪里出错了?
问题分析与修正方案
1. Mongoose模型与实际数据库结构不匹配
你的实际MongoDB文档是以大学名称(如UMKC、UNT)为顶级键,每个键下嵌套users对象,再分professors/students/admins数组。但你定义的userSchema是单个用户的字段结构,完全不符合数据库存储的文档格式,这会导致Mongoose无法正确识别和操作数据。
2. updateOne筛选条件写法错误
你写的await Users.updateOne({filter}, ...)是错误的,filter本身就是一个查询对象,不需要额外用大括号包裹,正确写法应为await Users.updateOne(filter, ...)。
3. 动态字段路径写法错误
用变量(如univName)生成字段路径时,不能直接写[${univName}].users.admins,正确的动态路径应该用ES6模板字符串拼接成完整路径:${univName}.users.admins,并在$push的对象中用方括号包裹路径变量。
修正后的代码
第一步:重新定义Mongoose模型
根据实际数据库结构调整Schema:
const mongoose = require('mongoose'); // 单个用户的子文档结构 const userSubSchema = new mongoose.Schema({ fname: String, lname: String, email: String, id: Number, password: String }); // 主文档:适配以大学名称为顶级键的结构,关闭strict模式允许未定义字段 const universityUserSchema = new mongoose.Schema({}, { strict: false }); const Users = mongoose.model('Users', universityUserSchema); module.exports = Users;
第二步:修正接口代码
router.post('/register', async (req, res) => { const { fname, lname, email, univName, id, role, password, _id } = req.body; const userData = { fname, lname, email, id, password }; const filter = { _id: new mongoose.Types.ObjectId(_id) }; // 动态生成目标数组路径,比如univName=UMKC、role=admin时,路径为"UMKC.users.admins" const pushPath = `${univName}.users.${role}s`; try { const updateResult = await Users.updateOne( filter, { $push: { [pushPath]: userData } } ); console.log(updateResult); res.status(200).json({ success: true, updateResult }); } catch (error) { console.log(error); res.status(500).json({ success: false, error: error.message }); } });
额外检查点
- 确保
univName参数和数据库中的顶级键完全一致(注意大小写,比如UMKC不能写成umkc) - 检查
_id参数是否正确,且已转换为mongoose.Types.ObjectId类型 - 查看
updateResult中的matchedCount和modifiedCount:若matchedCount为0,说明没有匹配到目标文档;若modifiedCount为0,说明路径或数据存在问题
内容的提问来源于stack exchange,提问作者Sasidhar Mankala
相关产品推荐
相关产品推荐

