使用 Mongoose populate() 清理死引用
Clean up dead references with Mongoose populate()
如果用户有一个名为 "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
}
});
然后我在查询中执行填充('tags'):
User.findById(req.params.id)
.populate("tags")
.exec(function(err, user) { ... });
如果列表中的某个标签实际上已被删除,有没有办法删除 "tags" 中的这个无效引用?
目前,返回的用户对象 是 返回所需的结果 -- 即。只有实际存在的标签在标签数组中...但是,如果我查看 mongodb 中的基础文档,它仍然包含数组中的死标签 ID。
理想情况下,我想懒惰地清理这些引用。有谁知道这样做的好策略吗?
假设你通过 mongoose 删除这些标签,你可以使用 post 中间件。
这将在您删除标签后执行。
tagSchema.post('remove', function(doc) {
//find all users with referenced tag
//remove doc._id from array
});
我试图找到一些内置的方法来做到这一点,但猫鼬似乎没有提供这样的功能。
所以我做了这样的事情
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();
}
如果用户有一个名为 "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
}
});
然后我在查询中执行填充('tags'):
User.findById(req.params.id)
.populate("tags")
.exec(function(err, user) { ... });
如果列表中的某个标签实际上已被删除,有没有办法删除 "tags" 中的这个无效引用?
目前,返回的用户对象 是 返回所需的结果 -- 即。只有实际存在的标签在标签数组中...但是,如果我查看 mongodb 中的基础文档,它仍然包含数组中的死标签 ID。
理想情况下,我想懒惰地清理这些引用。有谁知道这样做的好策略吗?
假设你通过 mongoose 删除这些标签,你可以使用 post 中间件。
这将在您删除标签后执行。
tagSchema.post('remove', function(doc) {
//find all users with referenced tag
//remove doc._id from array
});
我试图找到一些内置的方法来做到这一点,但猫鼬似乎没有提供这样的功能。
所以我做了这样的事情
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();
}