假设我们有一个这样的模式:
const PageSchema = new mongoose.Schema({
content: String
order: Number
})
我们希望order
始终是0
和之间的唯一数字n-1
,其中n
是文档总数。
插入或删除文档时如何确保?
对于插件,我目前使用此钩子:
PageSchema.pre('save', async function () {
if (!this.order) {
const lastPage = await this.constructor.findOne().sort({ order: -1 })
this.order = lastPage ? lastPage.order + 1 : 0
}
})
当插入新文档时,这似乎起作用。删除文档后,我将不得不减少的order
文档order
。但是,我不确定删除文档时会调用哪个挂钩。
效率对我来说不是问题:插入和删除没有很多。如果我能以某种方式仅提供一个fix_order
对整个集合进行迭代的功能,那完全没问题。如何安装此功能,以便在插入或删除文档时调用它?
您可以使用findOneAndDelete之前和之后的钩子来完成此操作。
正如您在findOneAndDelete之前的挂钩中所看到的,我们保存了对已删除文档的引用,并将其传递给postfindOneAndDelete,以便我们可以使用构造函数访问模型,并使用updateMany方法来调整顺序。
PageSchema.pre("findOneAndDelete", async function(next) {
this.page = await this.findOne();
next();
});
PageSchema.post("findOneAndDelete", async function(doc, next) {
console.log(doc);
const result = await this.page.constructor.updateMany(
{ order: { $gt: doc.order } },
{
$inc: {
order: -1
}
}
);
console.log(result);
next();
});
假设您有以下3个文档:
[
{
"_id": ObjectId("5e830a6d0dec1443e82ad281"),
"content": "content1",
"order": 0,
"__v": 0
},
{
"_id": ObjectId("5e830a6d0dec1443e82ad282"),
"content": "content2",
"order": 1,
"__v": 0
},
{
"_id": ObjectId("5e830a6d0dec1443e82ad283"),
"content": "content3",
"order": 2,
"__v": 0
}
]
当"_id": ObjectId("5e830a6d0dec1443e82ad282")
使用findOneAndDelete方法删除content2时,如下所示:
router.delete("/pages/:id", async (req, res) => {
const result = await Page.findOneAndDelete({ _id: req.params.id });
res.send(result);
});
中间件将运行,并调整顺序,其余2个文档如下所示:
[
{
"_id": ObjectId("5e830a6d0dec1443e82ad281"),
"content": "content1",
"order": 0,
"__v": 0
},
{
"_id": ObjectId("5e830a6d0dec1443e82ad283"),
"content": "content3",
"order": 1, => DECREASED FROM 2 to 1
"__v": 0
}
]
同样,您最好将下一个包含在预保存的中间件中,以便以后添加其他中间件时也可以使用。
PageSchema.pre("save", async function(next) {
if (!this.order) {
const lastPage = await this.constructor.findOne().sort({ order: -1 });
this.order = lastPage ? lastPage.order + 1 : 0;
}
next();
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句