You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose:如何从文档对象的数组中删除指定值?

问题:MongoDB嵌套数组删除指定ProductId失败,改用await后解决

问题场景

我在开发学校作业的网店项目,需要从webshop文档的categories数组下的products子数组中删除指定的productId。一开始尝试了两种写法,都无法成功删除前端传入的目标产品:

第一种写法:

webshopCollection.findByIdAndUpdate(req.body.webshop, {
  categories: { $pull: { products: productId } },
});

第二种写法:

webshopCollection.findByIdAndUpdate(req.body.webshop, {
  $pull: { categories: { products: productId } },
});

原完整函数代码如下:

const productId = req.body.productId;
productsCollection
  .deleteOne({ _id: productId })
  .then(() =>
    webshopCollection.findByIdAndUpdate(req.body.webshop, {
      $pull: { products: productId },
    })
  )
  .then(() => {
    webshopCollection.findByIdAndUpdate(
      req.body.webshop,
      {
        $pull: {
          "categories.$[category].products": productId,
        },
      },
      {
        arrayFilters: [
          {
            "category.products": productId,
          },
        ],
      }
    );
  })
  .then(() => {
    return res
      .status(200)
      .json({ message: "Product deleted successfully" });
  })
  .catch((error) => {
    console.log(error);
    return res
      .status(400)
      .json({ error: "Something went wrong. Please try again later" });
  });

问题根源

原代码的Promise链式调用存在逻辑漏洞:第三个then回调中调用webshopCollection.findByIdAndUpdate时,没有返回这个异步操作的Promise对象,导致链式调用不会等待该数据库操作完成,直接进入下一个then返回成功响应。此时嵌套数组的删除操作可能还未执行完毕,所以前端看起来删除未生效。

修正后的代码

改用await关键字逐个等待异步操作完成,确保所有数据库操作按顺序执行后再返回响应,问题得以解决:

const productId = req.body.productId;
await productsCollection.deleteOne({ _id: productId });
await webshopCollection.findByIdAndUpdate(req.body.webshop, {
  $pull: { products: productId },
});
await webshopCollection
  .findByIdAndUpdate(
    req.body.webshop,
    {
      $pull: {
        "categories.$[category].products": productId,
      },
    },
    {
      arrayFilters: [
        {
          "category.products": productId,
        },
      ],
    }
  )
  .then(() => {
    return res
      .status(200)
      .json({ message: "Product and references deleted successfully" });
  })
  .catch((error) => {
    return res
      .status(400)
      .json({ error: error });
  });

内容的提问来源于stack exchange,提问作者badatcoding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 06:10:12