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

Mongoose findByIdAndRemove返回null,如何删除用户嵌套数组中的笔记?

问题:无法删除User文档中notes数组内的指定笔记

我原本尝试用Mongoose的findByIdAndRemove方法删除笔记,但执行时console.log(foundNote)返回null。后来发现找错了位置——实际要删除的是User文档里notes数组中指定_id的笔记,不知道正确实现方式。

我的相关代码和数据结构如下:

当前删除接口代码

app.post("/delete", async (req, res) => {
const userId = req.session.userId;
const foundUser = await User.findById(userId).exec();
console.log(foundUser);
if (foundUser) {
    const itemId = req.body.itemId.toString();
    const foundNote = await Note.findByIdAndRemove(itemId).exec();
    console.log(foundNote);
    if (foundNote) {
        res.redirect("/main")
}
}
});

User对象结构

{
_id: new ObjectId("6537d3aa0bf4dd1fb949f084"),
username: 'test9@email.com',
notes: [
{
  noteBody: 'test9a',
  userId: '6537d3aa0bf4dd1fb949f084',
  _id: new ObjectId("6537d3ba0bf4dd1fb949f08a")
}
],
__v: 1
}

Schema定义

const userSchema = new mongoose.Schema ({
email: String,
password: String,
notes: [noteSchema]
});

const noteSchema = new mongoose.Schema ({
noteBody: String,
userId: String
});

解决方案

因为你的笔记是嵌套在User文档的notes数组里的子文档,并非独立的Note集合文档,所以不能直接用Note.findByIdAndRemove操作。可以用Mongoose的数组更新操作符实现:

方法1:使用findByIdAndUpdate结合$pull(推荐,原子操作)

app.post("/delete", async (req, res) => {
  const userId = req.session.userId;
  const itemId = req.body.itemId.toString();

  // 找到用户并从notes数组中移除指定_id的子文档
  const updatedUser = await User.findByIdAndUpdate(
    userId,
    { $pull: { notes: { _id: itemId } } },
    { new: true } // 返回更新后的文档
  ).exec();

  if (updatedUser) {
    res.redirect("/main");
  } else {
    res.status(404).send("用户不存在");
  }
});

方法2:先查询用户再操作数组(适合需额外逻辑的场景)

app.post("/delete", async (req, res) => {
  const userId = req.session.userId;
  const itemId = req.body.itemId.toString();

  const foundUser = await User.findById(userId).exec();
  if (!foundUser) {
    return res.status(404).send("用户不存在");
  }

  // 过滤掉指定_id的笔记
  foundUser.notes = foundUser.notes.filter(note => note._id.toString() !== itemId);
  await foundUser.save();

  res.redirect("/main");
});

说明

  • $pull操作符会从数组中移除所有匹配指定条件的元素,这里匹配的是notes数组中_id等于itemId的子文档
  • 方法1是数据库层面的原子操作,效率更高;方法2适合需要在更新前对数组做额外处理的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:25:10