【问题标题】:What to do if operations after Mongoose findOneAndUpdate failMongoose findOneAndUpdate 操作失败怎么办
【发布时间】:2020-08-03 11:12:51
【问题描述】:

我有一个 Mongoose 架构,它的属性是 ObjectId 子文档的数组。

如果需要删除/删除其中一个子文档,我当然想从父的数组属性中删除它。

我的问题是:我按什么顺序对子项执行删除/删除操作,对父项执行 findOneAndUpdate 操作?

我问的原因是,如果我先成功删除/删除子项,但随后从父项的数组属性中删除 ObjectId 时出错,则子项似乎仍存在于父项下。

但是,如果我先从父级删除 ObjectId,然后在删除/删除子级时遇到问题,我认为没有办法在删除 ObjectId 之前将父级恢复为如果我能帮上忙,我宁愿不要有孤立的文件。

我在这一点上想出的东西感觉很“骇人听闻”,并且可能反过来产生自己的错误:

  async deleteForm(req,res,next) {
    let currentLocation;
    try {
      //Remove the reference to the Form from the 'forms' array in the parent 'Location'
      try {
        currentLocation = await Location.findOneAndUpdate(
          {
            forms: mongoose.types.ObjectId(req.params.formId)
          }, 
          {
            $pull: {forms: req.params.formId}
          }
        );
      } catch (err) {
        console.error(err)
        throw new Error('Error removing Form from Location')
      }

      //Actually find and remove the 'Form' itself
      try {
        await Form.findByIdAndRemove(req.params.formId);
      } catch (err) {
        console.error(err);
        /* If the 'Form' can't be removed, re-add the reference to the form back into the 
         parent 'Location's 'forms' array*/
        await currentLocation.update({
          $push: {forms: mongoose.types.ObjectId(req.params.formId)}
        })
        throw new Error('Error deleting Form')
      }

    } catch (err) {
      req.session.error = err;
    } finally {
      res.redirect(`/locations/${currentLocation._id}`);
    }
  }

【问题讨论】:

    标签: javascript node.js database mongoose


    【解决方案1】:

    您可以先对子文档运行删除操作,然后对父文档运行更新操作。如果您使用回调,您可以将第二个操作嵌套在第一个操作的.then 块下,这样您就可以保证子文档。在更新父文档之前被删除。

    【讨论】:

    • 如果我不想使用回调,是否可以将Form delete 方法包装在一个promise 中,然后使用Promise.then() 更新Location
    • 是的。只要存在.then(),就必须先解决promise,然后才能执行块中的代码。它可能会解决您的问题。
    【解决方案2】:

    感谢@Aviv Lo 提醒我回调和Promise.then() 是一回事。老实说,每次我发布问题时,我都会感到很新鲜。

    这就是我最终得到的结果:

    async deleteForm(req,res,next) {
        let currentLocation;
        try {
          //Find the parent location, to be updated after deleting the form
          try {
            currentLocation = await Location.findOne(
              {
                forms: mongoose.Types.ObjectId(req.params.formId)
              }
            );
          } catch (err) {
            console.error(err)
            throw new Error('Error removing Form from Location')
          } 
    
          //Actually find and remove the 'Form' itself
          try {
            new Promise(async (resolve, reject) => {
              try {
                await Form.findByIdAndRemove(req.params.formId);
                resolve();
              } catch (err) {
                reject(err);
              }
            })
            /* only after the form is deleted, remove the reference from the parent 
            Location */
            .then(async () => {
              await currentLocation.update({
                $pull: {forms: mongoose.Types.ObjectId(req.params.formId)}
              });
            });
          } catch (err) {
            console.error(err);        
            throw new Error('Error deleting Form')
          }
          req.session.success = 'Form deleted!'
        } catch (err) {
          req.session.error = err;
        } finally {
          res.redirect(`/locations/${currentLocation._id}`);
        }
      }
    

    【讨论】:

      猜你喜欢
      • 2017-03-20
      • 1970-01-01
      • 2021-10-22
      • 1970-01-01
      • 2011-04-26
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 2011-09-03
      相关资源
      最近更新 更多