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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:54:02