Clean up dead references with Mongoose populate()

别说谁变了你拦得住时间么 提交于 2021-02-18 18:59:49

问题


If a user has an array called "tags":

var User = new Schema({
    email: {
        type: String,
        unique: true,
        required: true
    },
    tags: [{
        type: mongoose.Schema.Types.ObjectId,
        ref:'Tag',
        required: true
    }],
    created: {
        type: Date,
        default: Date.now
    }
});

and I do a populate('tags') on a query:

User.findById(req.params.id)
    .populate("tags")
    .exec(function(err, user) { ... });

If one of the tags in the list has actually been deleted, is there a way to remove this dead reference in "tags"?

Currently, the returned user object IS returning the desired result -- ie. only tags that actually exist are in the tags array... however, if I look at the underlying document in mongodb, it still contains the dead tag id in the array.

Ideally, I would like to clean these references up lazily. Does anyone know of a good strategy to do this?


回答1:


I've tried to find some built-in way to do that but seems that mongoose doesn't provide such functionality.

So I did something like this

User.findById(userId)
    .populate('tags')
    .exec((err, user) => {
        user.tags = user.tags.filter(tag => tag != null);

        res.send(user); // Return result as soon as you can
        user.save(); // Save user without dead refs to database
    })

This way every time you fetch user you also delete dead refs from the document. Also, you can create isUpdated boolean variable to not call user.save if there was no deleted refs.

const lengthBeforeFilter = user.tags.length;
let isUpdated = user.tags.length;

user.tags = user.tags.filter(tag => tag != null);
isUpdated = lengthBeforeFilter > user.tags.length;

res.send(user);

if (isUpdated) {
    user.save();
}



回答2:


Assuming you delete these tags via mongoose, you can use the post middleware.

This will be executed after you've deleted a tag.

tagSchema.post('remove', function(doc) {
     //find all users with referenced tag
     //remove doc._id from array
});


来源:https://stackoverflow.com/questions/41214664/clean-up-dead-references-with-mongoose-populate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!