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

求助:向MongoDB数组推送元素仅生成空对象问题排查

问题根源:Schema里的字段类型键写错了!

老兄,我一眼就揪出问题所在了——你的ParticipantSchema里字段的类型定义用了大写的Type,但Mongoose要求这个键必须是小写的type!Mongoose根本识别不了Type这个属性,所以当你往数组里推新元素时,它只会生成默认的_id,完全忽略你传入的nom、prenom、email字段,最终就出现了那些只剩_id的空对象。

第一步:修正你的Schema定义

把ParticipantSchema里的Type全部改成小写的type,修正后的代码如下:

const Schema = mongoose.Schema;
var ParticipantSchema = new Schema({
    nom: { type: String }, // 这里改成小写type
    prenom: { type: String }, // 这里改成小写type
    email: { type: String } // 这里改成小写type
})
var CompetitionSchema = new Schema({
    nom: String,
    date: Date,
    place: String,
    participant :[ParticipantSchema]
})
module.exports = mongoose.model("Competition",CompetitionSchema);

第二步:可选优化你的addParticipant函数

你当前用updateOne的写法没问题,但可以换成findByIdAndUpdate让代码更直观,同时加上{ new: true }选项能直接返回更新后的文档,方便你验证结果:

exports.addParticipant=function(req,res){
    var newParticipant={
        "nom":req.body.nom,
        "prenom":req.body.prenom,
        "email":req.body.email
    }
    Competition.findByIdAndUpdate(
        req.body.id, // 直接传id,Mongoose会自动转成ObjectId
        { $push: { participant: newParticipant } },
        { new: true, runValidators: true }, // new返回更新后的数据,runValidators确保字段验证生效
        (err, updatedCompetition)=>{
            if(err) return res.status(500).json(err);
            return res.json(updatedCompetition);
        }
    );
}

如果你更喜欢逻辑更清晰的写法,也可以用「先查询再保存」的方式:

exports.addParticipant=async function(req,res){ // 用async/await让代码更简洁易读
    try{
        const competition = await Competition.findById(req.body.id);
        if(!competition) return res.status(404).json({message: "赛事不存在"});
        
        competition.participant.push({
            nom: req.body.nom,
            prenom: req.body.prenom,
            email: req.body.email
        });
        
        const updatedCompetition = await competition.save();
        return res.json(updatedCompetition);
    }catch(err){
        return res.status(500).json(err);
    }
}

验证效果

修改完成后再添加参与者,你的participant数组里就会出现完整的对象了:

{
    "_id": "5ded0eeb85daa100dc5e57bf",
    "nom": "Final",
    "date": "2019-01-01T23:00:00.000Z",
    "place": "Sousse",
    "participant": [
        { 
            "_id": "5ded0eeb85daa100dc5e57c0",
            "nom": "Doe",
            "prenom": "John",
            "email": "john@example.com"
        }
    ],
    "__v": 0
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:53:25