首页 > 解决方案 > 如何根据 ObjectId 删除嵌套对象?

问题描述

我的课程集合有这个嵌套模式,每个课程中有一个会话数组,每个会话中有一个学生数组,每个学生都是一个对象,由 userName 的属性和 ObjectId 的值组成,引用我的用户集合和另一个属性名称状态包含一些数字。

我想从我的会话的学生数组中删除一个学生对象及其_id。

我知道可以展开数组以获取单个对象,但我需要一种简洁的方法,例如使用 objectId 从数据库中删除对象,这样我们就不必像直接删除或修改嵌套子文档那样指定路径。

这是我的课程架构:

 CourseSchema = new mongoose.Schema({
    name:String,
    sessions:[
        {
         date:Date,
         students :[{
             userName:{
                type:mongoose.Schema.Types.ObjectId,
                ref :'users'
             },
             status:Number
         }]   
        }
    ]
})

标签: node.jsmongodbexpressmongooseaggregate

解决方案


您可以使用以下 DELETE 路由从课程会话中删除学生。

router.delete(
  "/course/:courseId/session/:sessionId/student/:studentId",
  async (req, res) => {
    try {
      let result = await Course.updateOne(
        { _id: req.params.courseId, "sessions._id": req.params.sessionId },
        {
          $pull: { "sessions.$.students": { userName: req.params.studentId } }
        }
      );

      res.send(result);
    } catch (err) {
      console.log(err);
      res.status(500).send("Something went wrong");
    }
  }
);

假设您有这样的课程:

{
    "_id" : ObjectId("5de907acdfcef9493cd215a8"),
    "name" : "Course 1",
    "sessions" : [
        {
            "date" : ISODate("2019-12-05T16:32:41.998+03:00"),
            "_id" : ObjectId("5de907acdfcef9493cd215a9"),
            "students" : [
                {
                    "_id" : ObjectId("5de907acdfcef9493cd215ac"),
                    "userName" : ObjectId("5de8e4c8f74cf254d04f90d8"),
                    "status" : 1
                },
                {
                    "_id" : ObjectId("5de907acdfcef9493cd215ab"),
                    "userName" : ObjectId("5de8e4d5f74cf254d04f90d9"),
                    "status" : 1
                },
                {
                    "_id" : ObjectId("5de907acdfcef9493cd215aa"),
                    "userName" : ObjectId("5de8e4ddf74cf254d04f90da"),
                    "status" : 1
                }
            ]
        }
    ],
    "__v" : 0
}

如果我们想删除 userName 和 value 的学生5de8e4ddf74cf254d04f90da,我们可以使用这样的 url 向我们的路由发送 DELETE 请求:

http://localhost/courses/5de907acdfcef9493cd215a8/session/5de907acdfcef9493cd215a9/student/5de8e4ddf74cf254d04f90da

5de907acdfcef9493cd215a8--> courseId

5de907acdfcef9493cd215a9--> sessionId

响应将是这样的:

{
    "n": 1,
    "nModified": 1,
    "ok": 1
}

当我们查看我们的课程时,我们看到学生被删除:

{
    "_id" : ObjectId("5de907acdfcef9493cd215a8"),
    "name" : "Course 1",
    "sessions" : [
        {
            "date" : ISODate("2019-12-05T16:32:41.998+03:00"),
            "_id" : ObjectId("5de907acdfcef9493cd215a9"),
            "students" : [
                {
                    "_id" : ObjectId("5de907acdfcef9493cd215ac"),
                    "userName" : ObjectId("5de8e4c8f74cf254d04f90d8"),
                    "status" : 1
                },
                {
                    "_id" : ObjectId("5de907acdfcef9493cd215ab"),
                    "userName" : ObjectId("5de8e4d5f74cf254d04f90d9"),
                    "status" : 1
                }
            ]
        }
    ],
    "__v" : 0
}

正如我们所见,5de8e4ddf74cf254d04f90da在课程会话中不再存在用户名和值的学生,这意味着它已被删除。


推荐阅读