NodeJS操作MongoDB时删除文档数组元素保存后仍存在的问题解决
Mongoose购物车数组元素删除异常问题修复
问题描述
购物车功能Schema设计中,购物车内每个商品对应products数组中的一个对象,包含productId和quantity两个字段。每次调用扣减函数时,会将传入的productId对应的商品数量减1,预期逻辑为:
- 若商品原数量大于1,仅扣减数量
- 若原数量为1,扣减后数量为0,需将该商品对象从products数组中完全移除
实际运行时仅扣减数量的逻辑运行正常,删除数组元素的逻辑触发后,接口返回「Deleted item in cart.」提示,但数据库中对应商品元素仍然未被删除。
Cart Schema代码
const mongoose = require('mongoose'); const idValidator = require('mongoose-id-validator'); const Schema = mongoose.Schema; const cartSchema = new Schema ({ products: [ { productId: { type: mongoose.Types.ObjectId, required: true, ref: 'Product' }, quantity: { type: Number, required: true }, } ], customer: { type: mongoose.Types.ObjectId, required: true, unique: true, ref: 'User'} }); cartSchema.plugin(idValidator); module.exports = mongoose.model('Cart', cartSchema);
原始扣减函数代码
const removeToCartByUserId = async (req, res, next) => { const userId = req.params.uid; const { productId } = req.body; const quantity = 1; try { let cart = await Cart.findOne({customer: userId}); //Cart exist for user if(cart) { let itemIndex = cart.products.findIndex(p => p.productId == productId); //product exists in the cart, update the quantity if (itemIndex > -1) { let productItem = cart.products[itemIndex]; if(productItem.quantity > 1) { productItem.quantity -= quantity; cart = await cart.save(); res.status(201).json({ cart }); } else { // delete product in array await cart.products.pull({ productId: productId }) // removed cart = await cart.save(); res.status(200).json({ message: 'Deleted item in cart.' }); } } } else { // no Cart for the user, exit const error = new HttpError('Something went wrong with the cart.', 500); return next(error); } } catch(err) { console.log(err); const error = new HttpError('Something went wrong with the cart.', 500); return next(error); } };
问题原因
- 原始代码中调用
cart.products.pull()匹配元素时,Schema定义的productId为ObjectId类型,若传入的productId为字符串类型,会出现类型不匹配导致定位元素失败,无法完成删除 - 部分Mongoose版本对嵌套数组的pull操作变更检测存在异常,即使pull操作执行成功,调用
cart.save()时也不会将数组变更同步到数据库
修复后可正常运行的代码
//product exists in the cart, update the quantity if (itemIndex > -1) { let productItem = cart.products[itemIndex]; productItem.quantity -= quantity; if(productItem.quantity > 0) { cart = await cart.save(); res.status(201).json({ cart }); } else { // delete product in array await Cart.updateOne( { customer: userId }, {$pull : { "products": { productId } } } ); res.status(200).json({ message: 'Deleted item in cart.' }); } }
内容的提问来源于stack exchange,提问作者fraaa
相关产品推荐
相关产品推荐

