【问题标题】:How to delete an nested object based on its ObjectId?如何根据 ObjectId 删除嵌套对象?
【发布时间】:2020-03-30 06:26:05
【问题描述】:

我的 courses 集合有这个嵌套架构,每门课程都有一个 sessions 数组,每个会话都有一个 students 数组,并且每个学生都是一个对象,由 userName 的一个属性组成,该属性的值 ObjectId 引用我的用户集合,另一个属性名称 status 包含一些数字。

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

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

这是我的课程架构:

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

【问题讨论】:

    标签: node.js mongodb express mongoose aggregate


    【解决方案1】:

    您可以使用以下 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 值为 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 的学生在课程会话中不再存在,这意味着它已被删除。

    【讨论】:

    • tnx 这可能会有所帮助,但我有点希望有一些函数可以根据其 uniq ObjectId 直接删除一个对象 .... 似乎没有
    • @Millw0 如果会话和学生有自己的单独收藏,这将是可能的。在您的情况下,它们嵌入在课程集合中,因此我认为您不能直接删除学生。但如果我找到另一种方法,我会更新答案。
    • @Millw0 实际上似乎还有另一种方法,如果我能做到,我会更新答案。
    • @Millw0 我更新了答案,我认为这正是你想要的。
    • thnx @SuleymanSah 修改后的版本是一种更简洁方便的方法......但我一开始所寻求的来自对 mongo 所做的一些可能错误的看法......因为mongo 中的每个对象都有自己的对象 ID,我想为什么我们不能仅根据其 objectID 删除子文档。我的意思是这个对象在内存中的某个地方,所以为什么 mongo 不能仅根据其对象 ID 来获取子文档……一种规避从主文档查询并直接访问嵌入在文档子文档中的每个对象的方法跨度>
    猜你喜欢
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 2018-01-22
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多