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

Node.js开发购物车后端时如何避免新增重复商品而是增加已有商品数量?

问题修复步骤


1. 先修正数据模型的错误配置

你当前Schema中给userId设置了unique: true约束,这会导致同一个用户只能存在一条购物车记录,完全无法添加多个不同商品,首先移除该约束:

module.exports = (mongoose) =>
    new mongoose.Schema(
    {
      // 移除unique: true,只保留必填约束
      userId: { type: Number, required: true },
      product: {
        productId: { type: Number, required: true },
        slug: { type: String, required: true },
        name: { type: String, required: true },
        image: { type: String, required: true },
      },
      options: [
        {
          optionId: { type: Number, required: true },
          optionTitle: { type: String, required: true },
          valueId: { type: Number, required: true },
          valueTitle: { type: String, required: true },
        },
      ],
      price: { type: Number, required: true },
      quantity: { type: Number, required: true, min: 1 },
    },
    { timestamps: true }
  );

2. 重写service层addItem方法

直接用MongoDB的findOneAndUpdate+upsert特性,一步实现「存在则更新数量、不存在则新建条目」的逻辑,无需手动判断是否存在:

注意:查询条件同时匹配userId、product.productId和options,确保同个商品不同规格会被识别为不同购物车条目

const db = require('../models');
const logger = require('../utils/logger');

const service = 'cart';
const tag = service + '.js';

module.exports = {
    addItem: async (payload, auth) => {
    try {
      const userId = auth.credentials.customerId;
      // 查询条件:匹配用户、商品ID、商品规格
      const query = {
        userId,
        'product.productId': payload.product.productId,
        options: payload.options // 完全匹配商品规格,不同规格算不同条目
      };
      // 更新操作:存在则累加数量,不存在时插入的默认数据
      const update = {
        $inc: { quantity: payload.quantity }, // 累加数量
        $setOnInsert: {
          userId,
          product: payload.product,
          options: payload.options,
          price: payload.price
        }
      };
      // 配置upsert=true,找不到匹配项时自动新建
      const options = { upsert: true, new: true, runValidators: true };
      const updatedCart = await db.Cart.findOneAndUpdate(query, update, options);
      return { success: true, data: updatedCart };
    } catch (error) {
      logger.error(tag + ': add', error);
      return { success: false, data: error };
    }
  },
};

逻辑说明

  • $inc操作符:匹配到已有条目时,自动对quantity字段做增量更新,不用手动读取再赋值
  • $setOnInsert操作符:只有当触发新建操作(upsert)时才会写入这些字段,更新已存在条目时不会覆盖原有数据
  • new: true配置:返回更新/新建后的最新数据
  • runValidators: true配置:更新时也触发Schema的字段校验,避免非法数据写入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:54:05