我想使用mongoose中间件挂钩重新尝试保存文档,以防初始保存因重复键错误而失败。用例如下:
我的模型使用slugs进行识别,这是自动生成的。例如。 item
,item-2
,item-3
,...,item-n
。如果item
已经存在,则应该向slug添加一个计数器。我无法查看" next"因为我需要在任何情况下避免冲突,所以提前做好准备。
由于这个逻辑将涉及几个不同的模型,我想将它分离成一个mongoose插件。
这个想法是否可能?例如。 schema.post('save', handler)
仅在成功保存时执行。还有其他钩子,我可以利用它吗?
答案 0 :(得分:0)
我正在使用预保存挂钩检查slug是否已经存在以下代码,到目前为止似乎工作正常。
pageSchema.pre('save', function(next){
var page = this;
page.createdDT = new Date();
page.updatedDT = new Date();
page.slug = page.title.slug(); // create slug from title
var re = new RegExp(page.slug, 'i');
mongoose.models["page"].find({slug: { $regex: re}}, function(err, pages){
// slug doesn't exist, good to go
if(!err && !pages) return next();
var slugs = [];
// let's get all slugs
pages.forEach(function(page){
slugs.push(page.slug);
});
// keep increasing `i` until slug is unique
// set i to 1 to avoid hello-0
var i = 1;
var tempSlug = page.slug;
while(slugs.indexOf(tempSlug) >= 0){
tempSlug = page.slug + '-' + i;
i++;
}
//unique slug for example "hello-2"
page.slug = tempSlug;
next();
});
});
答案 1 :(得分:0)
我终于选择了mongoose-uniqueslugs
使用的解决方案,我根据自己的需要进行了调整。虽然这个变体不仅仅适用于前/后挂钩,但它确保原子性(即不提前检查可用的slu and然后保存,但只是重新尝试)。
中心思想是覆盖模型的save
函数(参见enhanceModel
函数)并提供一个包装器,它通过slug碰撞捕获唯一错误然后重新尝试保存(而不是附加的随机字符串,我们想要一个序号方法)。