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

解决MongoDB E11000重复键错误及购物车数据存取问题

解决E11000重复键错误&实现购物车功能方案

一、先修复当前的重复键错误

错误提示E11000 duplicate key error collection: test.products index: name_1 dup key: { name: "tomek" },但你的Product模型中name字段并未设置unique: true,说明数据库中已存在针对name字段的唯一索引,需要删除它:

  1. 打开MongoDB Shell,连接到目标数据库:
    mongosh
    use test
    
  2. 查看集合的所有索引:
    db.products.getIndexes()
    
  3. 删除name_1这个唯一索引:
    db.products.dropIndex("name_1")
    

二、重构购物车的正确实现

当前模型设计不符合购物车逻辑(同一个用户重复添加同一件商品应更新数量,而非创建新条目),需调整模型和接口逻辑:

1. 创建购物车条目模型(models/CartItem.js)

import mongoose from "mongoose";
const { Schema } = mongoose;

const cartItemSchema = new Schema({
  // 用户唯一标识(已登录用户email唯一)
  userEmail: {
    type: String,
    required: true,
  },
  // 商品本身的唯一ID(确保同一件商品ID一致)
  productId: {
    type: String,
    required: true,
  },
  // 商品基础信息(直接存储方便前端展示)
  productName: {
    type: String,
    required: true,
  },
  category: {
    type: String,
    required: true,
  },
  title: {
    type: String,
    required: true,
  },
  price: {
    type: String,
    required: true,
  },
  // 商品数量
  quantity: {
    type: Number,
    default: 1,
    min: 1,
  },
}, { timestamps: true });

// 联合唯一索引:同一个用户的同一件商品仅存一条记录
cartItemSchema.index({ userEmail: 1, productId: 1 }, { unique: true });

export default mongoose.models.CartItem || mongoose.model("CartItem", cartItemSchema);

2. 修改购物车添加接口(api/cart/route.js)

替换原api/products/route.js,或新建购物车专用接口:

import { NextResponse } from "next/server";
import CartItem from "@/models/CartItem";
import connect from "@/utils/db";

export const POST = async (request) => {
  const { userEmail, productId, productName, category, title, price } = await request.json();

  await connect();

  try {
    // 存在则数量+1,不存在则创建新条目
    await CartItem.findOneAndUpdate(
      { userEmail, productId },
      { $inc: { quantity: 1 }, $setOnInsert: { productName, category, title, price } },
      { upsert: true, new: true }
    );

    return new NextResponse("商品已添加到购物车", { status: 200 });
  } catch (err) {
    return new NextResponse("添加失败:" + err.message, { status: 500 });
  }
};

// 新增获取用户购物车列表的GET接口
export const GET = async (request) => {
  const { searchParams } = new URL(request.url);
  const userEmail = searchParams.get("userEmail");

  if (!userEmail) {
    return new NextResponse("缺少用户邮箱", { status: 400 });
  }

  await connect();

  try {
    const cartItems = await CartItem.find({ userEmail });
    return new NextResponse(JSON.stringify(cartItems), { status: 200 });
  } catch (err) {
    return new NextResponse("获取购物车失败:" + err.message, { status: 500 });
  }
};

3. 调整前端请求代码

注意:productId用商品本身的唯一ID,而非随机生成的ID:

// 假设current[0]是选中的商品,自带唯一id字段
const productId = current[0].id; 
const userEmail = session.data.user.email;
const productName = current[0].title;
const category = current[0].category;
const title = current[0].title;
const price = current[0].price;

try {
  const res = await fetch("/api/cart", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      userEmail,
      productId,
      productName,
      category,
      title,
      price,
    }),
  });

  if (res.ok) {
    console.log("商品已加入购物车");
    // 可在此处触发购物车列表刷新
  } else {
    const errMsg = await res.text();
    console.log("添加失败:", errMsg);
  }
} catch (err) {
  console.log("请求出错:", err);
}

4. 前端获取购物车列表代码

async function fetchCart() {
  const userEmail = session.data.user.email;
  try {
    const res = await fetch(`/api/cart?userEmail=${encodeURIComponent(userEmail)}`);
    if (res.ok) {
      const cartItems = await res.json();
      console.log("购物车列表:", cartItems);
      // 渲染购物车组件
    } else {
      console.log("获取购物车失败");
    }
  } catch (err) {
    console.log("请求出错:", err);
  }
}

三、额外说明

  • 原Product模型应用于存储商品目录,购物车需单独模型管理用户与商品的关联关系
  • 使用findOneAndUpdate的upsert选项可避免重复创建条目,自动处理数量更新
  • 联合唯一索引{userEmail:1, productId:1}确保同一个用户的同一件商品不会重复存储

内容的提问来源于stack exchange,提问作者tomaszM-dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 18:00:08