Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果字段';MongoDB&;中的s值达到0;Node.js_Node.js_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

如果字段';MongoDB&;中的s值达到0;Node.js

如果字段';MongoDB&;中的s值达到0;Node.js,node.js,mongodb,mongodb-query,aggregation-framework,Node.js,Mongodb,Mongodb Query,Aggregation Framework,我有像购物清单这样的对象数组。例如,我在列表中添加了2个产品 cart:[{id:1,quantity:15},{id:2,quantity:5}] 我可以很好地增加和减少数量,但我想做的是,当我减少到0时,我希望它显示为我的购物车中没有,我知道这可能是拉,我尝试了这个,但失败了。idk我做错了什么,当我尝试console.log(用户)时,它给我空值,因为它没有看到“cart.quantity”:0,idk为什么不。用户信息和布局是好的 router.get("/:productId/de

我有像购物清单这样的对象数组。例如,我在列表中添加了2个产品

cart:[{id:1,quantity:15},{id:2,quantity:5}]
我可以很好地增加和减少数量,但我想做的是,当我减少到0时,我希望它显示为我的购物车中没有,我知道这可能是拉,我尝试了这个,但失败了。idk我做错了什么,当我尝试console.log(用户)时,它给我空值,因为它没有看到“cart.quantity”:0,idk为什么不。用户信息和布局是好的


router.get("/:productId/decrement", auth, async (req, res) => {
  const user = await User.findOne({
    id: req.user._id,
    "cart.quantity": 0,
  });
  if (user) {
    await User.findOneAndUpdate(
      {
        id: req.user._id,
        "cart.id": req.params.productId,
        "cart.quantity": 0,
      },
      { $pull: { cart: { id: req.params.productId } } }
    );
  } else {
    await User.findOneAndUpdate(
      {
        id: req.user._id,
        "cart.id": req.params.productId,
      },
      { $inc: { "cart.$.quantity": -1 } },
      { new: true },
      (err, doc) => {
        if (err) {
          return res.json({ success: false, err });
        }
        return res.json({ success: true, cart: doc });
      }
    );
  }
});

这是我的用户模型

const userSchema = mongoose.Schema({
  name: {
    type: String,
    maxlength: 50,
  },
  email: {
    type: String,
    trim: true,
    unique: 1,
  },
  password: {
    type: String,
    minglength: 5,
  },
  lastname: {
    type: String,
    maxlength: 50,
  },
  cart: { type: Array, default: [] }, 

在MongoDB版本>=3.2:

router.get("/:productId/decrement", auth, async (req, res) => {
  try {
    let bulkArr = [
      {
        updateOne: {
          filter: {
            id: req.user._id,
            "cart.id": req.params.productId,
            "cart.quantity": 1, // You can use {$lte : 1}
          },
          update: { $pull: { 'cart': { id: req.params.productId } } },
        },
      },
      {
        updateOne: {
          filter: {
            id: req.user._id,
            "cart.id": req.params.productId
          },
          update: { $inc: { "cart.$.quantity": -1 } },
        },
      },
    ];
    await User.bulkWrite(bulkArr);
    return res.json({ success: true });
  } catch (error) {
    console.log("Error ::", error);
    return res.json({ success: false, ...{error} });
  }
});
注意:

router.get("/:productId/decrement", auth, async (req, res) => {
  try {
    let bulkArr = [
      {
        updateOne: {
          filter: {
            id: req.user._id,
            "cart.id": req.params.productId,
            "cart.quantity": 1, // You can use {$lte : 1}
          },
          update: { $pull: { 'cart': { id: req.params.productId } } },
        },
      },
      {
        updateOne: {
          filter: {
            id: req.user._id,
            "cart.id": req.params.productId
          },
          update: { $inc: { "cart.$.quantity": -1 } },
        },
      },
    ];
    await User.bulkWrite(bulkArr);
    return res.json({ success: true });
  } catch (error) {
    console.log("Error ::", error);
    return res.json({ success: false, ...{error} });
  }
});
  • 我相信您正在混合
    异步等待
    的&
    回调()
    。请尽量避免
  • bulkWrite
    中,将执行所有筛选条件,但仅当相应的筛选匹配(单个操作的种类)但在一个DB调用中时,才会执行更新操作
  • bulkWrite
    输出“写入结果”,但如果需要结果文档,则需要执行
    .find()
    调用。但由于使用
    bulkWrite
    的全部目的是避免多次调用数据库-如果结果没有错误,您可以向前端发送成功消息,然后它们可以显示适当的计数(通过执行递减)
  • Ref:


    在MongoDB版本>=4.2:

    router.get("/:productId/decrement", auth, async (req, res) => {
      try {
        let bulkArr = [
          {
            updateOne: {
              filter: {
                id: req.user._id,
                "cart.id": req.params.productId,
                "cart.quantity": 1, // You can use {$lte : 1}
              },
              update: { $pull: { 'cart': { id: req.params.productId } } },
            },
          },
          {
            updateOne: {
              filter: {
                id: req.user._id,
                "cart.id": req.params.productId
              },
              update: { $inc: { "cart.$.quantity": -1 } },
            },
          },
        ];
        await User.bulkWrite(bulkArr);
        return res.json({ success: true });
      } catch (error) {
        console.log("Error ::", error);
        return res.json({ success: false, ...{error} });
      }
    });
    
    由于我们可以在更新中使用聚合,您可以执行以下操作:

    User.findOneAndUpdate({id: req.user._id, 'cart.id': req.params.productId},
       [
        {
          $addFields: {
            cart: {
              $reduce: {
                input: "$cart",
                initialValue: [],
                in: {
                  $cond: [
                    { $and: [ { $eq: [ "$$this.id", req.params.productId ] }, { $gt: [ "$$this.quantity", 1 ] } ] }, // condition
                    {
                      $concatArrays: [ "$$value", [ { $mergeObjects: [ "$$this", { quantity: { $add: [ "$$this.quantity", -1 ] } } ] } ]]
                    }, // condition is true, So we're decrementing & pushing object to accumulator array
                    {
                      $cond: [ { $eq: [ "$$this.id", req.params.productId ] }, "$$value", { $concatArrays: [ "$$value", [ "$$this" ] ] } ]
                    } // condition failed, so pushing objects where id != input productId
                  ]
                }
              }
            }
          }
        }
      ], {new: true})
    
    参考:

    此处的测试聚合管道:

    注意:

    router.get("/:productId/decrement", auth, async (req, res) => {
      try {
        let bulkArr = [
          {
            updateOne: {
              filter: {
                id: req.user._id,
                "cart.id": req.params.productId,
                "cart.quantity": 1, // You can use {$lte : 1}
              },
              update: { $pull: { 'cart': { id: req.params.productId } } },
            },
          },
          {
            updateOne: {
              filter: {
                id: req.user._id,
                "cart.id": req.params.productId
              },
              update: { $inc: { "cart.$.quantity": -1 } },
            },
          },
        ];
        await User.bulkWrite(bulkArr);
        return res.json({ success: true });
      } catch (error) {
        console.log("Error ::", error);
        return res.json({ success: false, ...{error} });
      }
    });
    

    很少有MongoDB客户端会抛出一个错误,说“更新操作可能只包含原子运算符”,这种情况下您可以使用
    .update()
    或者使用代码测试它,因为大多数支持
    4.2
    的驱动程序都不会抛出这样的错误。

    您的MongoDB版本是什么?我的版本是5.4.20MongoDB版本
    4.2.x
    目前是最新版本!我猜这是您的驱动程序版本(如果我没记错的话,您可能正在使用mongoose)(驱动程序帮助将编程语言代码连接到数据库),我在询问MongoDB服务器版本。。您可以通过执行
    db.version()
    来获得它。是的,您是对的,它的mongoose,我通过npm下载了mongoose,但没有对mongodb做任何操作,只是使用网站上的应用程序代码来连接。我也应该安装吗?当你说网站是mongo atlas吗?如果是,那么当您登录到门户网站时,您可以看到MongoDB服务器版本,或者至少您可以在robo3T或shell(一旦连接到DB)中发出上述命令,以了解您正在使用的版本。谢谢您,我尝试了4.2,它工作得很好,但我仍然不知道为什么我的版本没有,尤其是User.findOne({id:req.User.\u id,“cart.quantity”: 0, });@托利马:不确定,
    id:req.user.\u id
    是否唯一?另外,您确定当您使用查询时,集合中是否存在任何匹配的单据?是的,它是唯一的,它给我空值,我希望它在我减量到之后匹配0@Tolima:尝试直接对数据库执行查询并检查结果,MongoDB文档中的
    id
    字段的类型是什么?检查输入类型是否与文档中的字段类型匹配(如果类型不匹配,通常不会得到任何文档,最终
    。findOne
    将返回
    null
    )当我发布增量请求时,查询工作正常,但我也注意到,当我减少或增加它时,它不是1乘1,这是另一个问题,您的代码也解决了它,所以我决定不关注我的旧代码,我必须了解$reduce部分,这似乎很难