【问题标题】:Mongoose deleting document referencesMongoose 删除文档引用
【发布时间】:2020-01-31 15:52:38
【问题描述】:

我有 2 个架构。一个用户架构和一个项目架构。用户模式包含对项目模式的引用。用户架构:

const UserSchema = new Schema({
    username: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    },
    password: {
        type: String,
        required: true
    },
    date: {
        type: Date,
        default: Date.now
    },
    projects: [
        {
            type: Schema.Types.ObjectId,
            ref: 'Project'
        }
    ]
});

项目架构:

const projectSchema = new Schema({
    experience: [
        {
            company: String,
            positionExperience: String,
            descriptionExperience: String,
            websiteExperience: String,
            timeperiodExperience: Array,
        }
    ],
    education: [
        {
            school: String,
            degree: String,
            descriptionEducation: String,
            websiteEducation: String,
            timeperiodEducation: Array
        },
    ],
}, {
        collection: 'project'
    });

当当前登录的用户保存一个项目时,它会被推送到用户模式中的项目数组中: user.projects.push(project);

我有一个删除路线,可以让用户删除项目:

router.delete('/delete/:id', passport.authenticate('jwt', { session: false }), (req, res, next) => {
    Project.findByIdAndRemove({ _id: req.params.id }, (err) => {
        if (err) res.json(err)
        else res.json('Succesfully removed')
    });
})

但是,项目 ID 不会从数据库中当前登录用户的集合中删除。数据库日志:

"_id" : ObjectId("5d9474c2dccfb181dd8e9fde"),
    "projects" : [
        ObjectId("5d9474cddccfb181dd8e9fdf"),
        ObjectId("5d94753e9b610a81f83937e9"),
        ObjectId("5d947602f72f0f820f2974f0"),
        ObjectId("5d947ae435d2e982535d9a53"),
    ],
    "username" : "b",
    "password" : "$2a$10$4T1TjmFYD/01wEdMbiSRMeKNVKegnkVBOGGHasP.qJjVbQzmgEZDO",
    "email" : "b",

所有项目都已删除,但其 ID 仍在用户记录中。我也需要某种垃圾收集来删除它们。我查看了级联删除。级联删除是指如果父表中的一条记录被删除,那么子表中对应的记录也会被自动删除。在我的情况下,用户是父表,我不是要删除用户,而是要删除与用户关联的项目。我尝试过这样的事情:

User.findOne({ username: req.user.username }, (err, user) => {
    Project.remove({
        "_id": {
            $in: user.projects
        }
    }, function(err) {
        if(err) return next(err);
        user.deleteOne()
    })
})

但这会删除整个用户...如何从项目集合中删除项目以及与登录用户对应的项目? 提前致谢。

* ----- 编辑 ----- *

经过更多的挖掘,并且感谢非常有用的答案,这就是我想出的:

//delete route
router.delete('/delete/:id', passport.authenticate('jwt', { session: false }), (req, res, next) => {
    User.findOneAndUpdate({ username: req.user.username }, {
        $pull: {
            'projects': req.params.id
        }
    }, function (err, model) {
        if (!err) {
            Project.findByIdAndRemove({ _id: req.params.id }, (err) => {
                if (err) res.json(err)
                else res.json('Succesfully removed')
            });
        }
        else {
            res.status(500).json(err)
        }
    });
})

【问题讨论】:

  • 代替deleteOne(),使用update() & $pull 并从用户对象中删除projectId
  • @MohammedAmirAnsari 感谢您的评论,我确实使用 $pull 将其从用户的收藏中删除。我已将上面的代码添加到我的问题中
  • 太好了...希望对您有所帮助:)

标签: node.js mongodb express mongoose


【解决方案1】:

您需要编写自己的删除函数。看看this question 已经处理了这个问题。

【讨论】:

  • 嘿,感谢您的评论,让我的代码正常工作。我已将其添加到上面的问题中,介意看看吗?
  • 您的解决方案应该可以工作。您是否有理由不使用链接问题中的预删除挂钩?恕我直言,这会更好。
【解决方案2】:
User.findOneAndUpdate({ username: req.user.username }, { $set : { projects : [] 
   } }, (err, user) => {
     Project.remove({
        "_id": {
        $in: user.projects
     }
  }, function(err) {
    if(err) return next(err);
    user.deleteOne()
  })
})

这样就可以解决问题,findOneAndUpdate 将返回原始文档而不是更新后的文档。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-05
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 2019-07-16
    • 2020-07-29
    相关资源
    最近更新 更多