猫鼬:始终保存文档顺序

玻璃

假设我们有一个这样的模式:

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章