用Mongoose populate()清理死引用

时间:2016-12-19 01:27:09

标签: mongodb mongoose mongoose-schema mongoose-populate

如果用户有一个名为"标记":

的数组
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
    }
});

我在查询中填充('标记'):

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

如果列表中的其中一个标签实际上已被删除,有没有办法在"标签&#34中删除这个死引用?

目前,返回的用户对象 IS 返回所需的结果 - 即。只有标签实际存在于tags数组中...但是,如果我查看mongodb中的底层文档,它仍然包含数组中的死标记id。

理想情况下,我想懒得清理这些引用。有没有人知道这样做的好策略?

2 个答案:

答案 0 :(得分:1)

我试图找到一些内置的方法,但似乎mongoose不提供这样的功能。

所以我做了类似的事情

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
    })

这样,每次获取用户时,您也会从文档中删除死引用。此外,如果没有删除引用,您可以创建isUpdated布尔变量以不调用user.save

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();
}

答案 1 :(得分:0)

假设你通过mongoose删除这些标签,你可以使用post中间件。

这将在您删除标签后执行。

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