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

如何使用Express和Mongoose向MongoDB中的嵌套数组添加对象

问题核心原因与解决方法

1. 修正Schema定义,匹配现有集合结构

你当前定义的EventSchema是把单个事件作为独立文档存储的,所以直接调用Event.create只会新建独立的事件文档,无法把数据塞到对应日期的events数组中。你需要按照你的集合结构重新定义Schema:

const mongoose = require("mongoose");

// 单个日程事件的子Schema
const EventItemSchema = new mongoose.Schema({
  event: {
    type: String,
    trim: true,
    required: true,
  },
  start: {
    type: String,
    trim: true,
  },
  end: {
    type: String,
    trim: true,
  },
  people: {
    type: String,
    trim: true,
    required: true,
  },
  location: {
    type: String,
    trim: true,
  },
  description: {
    type: String,
    trim: true,
  },
});

// 单日文档的Schema,对应你events集合里的每个文档
const DaySchema = new mongoose.Schema({
  // 对应月中第几天,和你请求参数里的chosenDay对应
  dayNumber: {
    type: Number,
    required: true,
    unique: true
  },
  // 存储当日所有事件的数组
  events: [EventItemSchema]
});

// 第三个参数明确指定映射到你现有的events集合
module.exports = mongoose.model("Day", DaySchema, "events");

注意:你现有的events集合中31个日期文档需要先补上dayNumber字段,值和前端传的chosenDay匹配(比如从0到30或者1到31),否则查询时会找不到对应文档。


2. 修改添加事件的接口逻辑

你之前写的Event[req.body.chosenDay].events.create是错误用法,Mongoose模型不支持通过下标直接取对应日期的文档,需要用MongoDB的$push更新操作符,找到对应日期的文档后往events数组追加内容:

// 导入修改后的Day模型
const Day = require("../models/Day");
exports.addEvent = async (req, res, next) => {
  try {
    const { event, start, end, people, location, description, chosenDay } = req.body;
    // 构造要添加的事件对象
    const newEvent = { event, start, end, people, location, description };
    // 找到对应日期的文档,往events数组追加新事件,new: true表示返回更新后的文档
    const updatedDay = await Day.findOneAndUpdate(
      { dayNumber: chosenDay },
      { $push: { events: newEvent } },
      { new: true, runValidators: true }
    );

    // 处理找不到对应日期的情况
    if (!updatedDay) {
      return res.status(404).json({
        success: false,
        error: "指定的日期不存在"
      });
    }

    return res.status(201).json({
      success: true,
      // 返回刚添加的事件数据
      data: updatedDay.events.slice(-1)[0],
    });
  } catch (err) {
    // 开发环境可打印err排查具体错误
    return res.status(500).json({
      success: false,
      error: "Server has failed",
    });
  }
};

扩展:删除事件的实现逻辑

如果要删除指定日期的指定事件,使用$pull操作符即可,示例:

await Day.findOneAndUpdate(
  { dayNumber: chosenDay },
  // 根据事件的_id删除对应条目
  { $pull: { events: { _id: 要删除的事件ID } } }
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 03:15:02