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

Mongoose通过ObjectId更新嵌套guests数组报错push不是函数如何解决

错误原因
  • 异步方法未加await:Event.findOne是异步查询方法,未加await时guest变量拿到的是Promise实例而非查询结果,Promise没有push方法,触发类型错误。
  • Schema定义不规范:当前guests数组直接将type设为Schema.Types.ObjectId,只能存储ObjectId值,无法附加attended字段,需要调整为嵌套子文档结构。
  • 查询与更新逻辑错误:查询条件'guests.ObjectId'是不存在的字段,且即使查询到Event文档,也需要先定位到guests数组中匹配的子元素再修改属性,不能直接对Event实例调用push。
修正方案

1. 修正Schema定义

const eventSchema = new Schema({
  address: String,
  description: String,
  guests: [
    {
      _id: Schema.Types.ObjectId, // 存储嘉宾对应的ObjectId
      attended: String // 存储签到状态
    }
  ],
});

2. 修正处理函数

方案A:查询后修改(适合需要做额外逻辑校验的场景)

module.exports.checkIn = async(req, res) => {
  try {
    // 查询包含对应嘉宾的活动文档
    const event = await Event.findOne({ 'guests._id': req.body.guest });
    if (!event) return res.status(404).json({ msg: '活动或嘉宾不存在' });
    // 定位匹配的嘉宾条目
    const targetGuest = event.guests.find(item => item._id.toString() === req.body.guest);
    targetGuest.attended = req.body.status;
    await event.save();
    res.status(200).json({ msg: '状态更新成功' });
  } catch (err) {
    res.status(500).json({ msg: '服务器错误', error: err.message });
  }
}

方案B:原子更新(性能更高,无需查询文档)

利用Mongoose的$定位符直接在数据库层面更新匹配的数组元素:

module.exports.checkIn = async(req, res) => {
  try {
    await Event.updateOne(
      { 'guests._id': req.body.guest },
      { $set: { 'guests.$.attended': req.body.status } }
    );
    res.status(200).json({ msg: '状态更新成功' });
  } catch (err) {
    res.status(500).json({ msg: '服务器错误', error: err.message });
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 17:24:02