Mongoose购物车添加商品时相同productId判断失效问题
购物车添加商品逻辑修复问题
问题背景
用户定义的Mongoose User Schema如下:
const userSchema = new mongoose.Schema( { name: { type: String, required: true }, email: { type: String, unique: true }, password: { type: String, required: true }, image: { type: String, required: true, default: 'placeholder.jpg' }, isAdmin: { type: Boolean, default: false }, cart: [ { product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product' }, quantity: { type: Number, required: true }, }, ], }, { timestamps: true } );
期望实现:添加商品到购物车时,若已存在相同productId的商品则增加数量,否则新增条目。但当前实现的addToCart函数每次都会重复添加条目,未正确累加数量:
export const addToCart = expressAsyncHandler(async (req, res) => { const { productId, quantity } = req.body; const user = await User.findById(req.user._id).select('cart'); if (user) { const productInCart = user.cart.find((item) => item.product === productId); if (productInCart) { productInCart.quantity += quantity; } else { user.cart.push({ productId, quantity }); } await user.save(); res.json(user); } else { res.status(401); throw new Error('User does not exist'); } });
问题原因
- 类型不匹配:
item.product是Mongoose的ObjectId对象,而productId是字符串类型,直接用===比较永远不相等,导致每次都判定为“商品未在购物车中”,执行新增逻辑。 - 字段名不匹配:push新条目时用了
productId作为键名,但Schema中定义的字段是product,虽然Mongoose会自动映射,但规范写法应该保持一致。
修复后的代码
export const addToCart = expressAsyncHandler(async (req, res) => { const { productId, quantity } = req.body; const user = await User.findById(req.user._id).select('cart'); if (user) { // 方法1:将ObjectId转为字符串后比较 const productInCart = user.cart.find((item) => item.product.toString() === productId); // 方法2:使用ObjectId的equals方法(更推荐) // const productInCart = user.cart.find((item) => item.product.equals(productId)); if (productInCart) { productInCart.quantity += quantity; } else { // 修正字段名,与Schema保持一致 user.cart.push({ product: productId, quantity }); } await user.save(); res.json(user); } else { res.status(401); throw new Error('User does not exist'); } });
额外优化建议
可以改用Mongoose的原子更新操作(如findOneAndUpdate),避免先查询再保存的两步操作,提升性能并减少并发问题:
export const addToCart = expressAsyncHandler(async (req, res) => { const { productId, quantity } = req.body; // 先尝试更新已有商品的数量 const updatedUser = await User.findOneAndUpdate( { _id: req.user._id, "cart.product": productId }, { $inc: { "cart.$.quantity": quantity } }, { new: true } ); if (updatedUser) { return res.json(updatedUser); } // 如果没有找到对应商品,添加新条目 const user = await User.findOneAndUpdate( { _id: req.user._id }, { $push: { cart: { product: productId, quantity } } }, { new: true } ); if (user) { res.json(user); } else { res.status(401); throw new Error('User does not exist'); } });
内容的提问来源于stack exchange,提问作者dyaipayan
相关产品推荐
相关产品推荐

