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

Mongoose更新嵌套对象数组前校验值存在性,实现购物车商品增改逻辑

问题原因

你当前代码的核心问题是只覆盖了「目标商品未加入购物车」的单一场景,没有处理商品已存在时的增量更新逻辑:

  • 过滤条件携带了"cart.product": { $nin: [req.body.id] }规则,当商品已经在购物车中时,查询无法匹配到对应文档,不会执行任何更新
  • 没有对查询到的商品信息做非空校验,传入无效商品ID时会直接触发后续计算报错
  • 缺少总金额totalPrice字段的同步更新逻辑,会导致明细和总金额数据不一致
修复后代码
router.put("/add-to-cart", authenticateToken, async (req, res) => {
    try {
        // 先校验商品是否存在
        const productInfo = await productSchema.findById(req.body.id);
        if (!productInfo) {
            return res.status(400).send({ status: false, message: "商品不存在" });
        }
        const addAmount = Number(req.body.amount) || 0;
        if (addAmount <= 0) {
            return res.status(400).send({ status: false, message: "添加数量必须大于0" });
        }
        const addPrice = addAmount * productInfo.productPrice;

        // 一次原子查询同时处理两种场景
        const updateResult = await cartSchema.findOneAndUpdate(
            // 只过滤用户,不限制购物车是否有该商品
            { user: req.user },
            [
                {
                    $set: {
                        // 先处理已存在商品的增量更新
                        cart: {
                            $map: {
                                input: "$cart",
                                in: {
                                    $cond: [
                                        { $eq: ["$$this.product", req.body.id] },
                                        {
                                            $mergeObjects: [
                                                "$$this",
                                                {
                                                    amount: { $add: ["$$this.amount", addAmount] },
                                                    price: { $add: ["$$this.price", addPrice] }
                                                }
                                            ]
                                        },
                                        "$$this"
                                    ]
                                }
                            }
                        },
                        totalPrice: { $add: ["$totalPrice", addPrice] }
                    }
                },
                {
                    // 商品不存在时插入新条目
                    $set: {
                        cart: {
                            $cond: [
                                { $in: [req.body.id, "$cart.product"] },
                                "$cart",
                                {
                                    $concatArrays: [
                                        "$cart",
                                        [{
                                            product: req.body.id,
                                            amount: addAmount,
                                            price: addPrice
                                        }]
                                    ]
                                }
                            ]
                        }
                    }
                }
            ],
            // 对应用户购物车不存在时自动创建
            { upsert: true, new: true, setDefaultsOnInsert: true }
        );

        return res.status(200).send({ status: true, data: updateResult });
    } catch (err) {
        res.status(500).send({ status: false, message: err.message });
    }
});
逻辑说明
  • 提前做商品有效性、添加数量的合法性校验,提前拦截非法请求
  • 用聚合更新的$map算子遍历购物车数组,匹配到对应商品时自动累加数量和金额,同步更新总金额
  • 用$cond判断商品是否已存在,不存在时才通过$concatArrays插入新的商品条目
  • 全程是单原子更新操作,不需要多次查询数据库,不存在并发更新的数据一致性问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:57:03