【问题标题】:how to avoid duplicate key error collection in mongodb如何避免mongodb中的重复键错误收集
【发布时间】:2021-09-20 20:35:23
【问题描述】:

我想为我的网站构建一个购物车,这是购物车的架构:

const productSchema = require("./product")[1];

const cartItemSchema = new Schema<CartItem>(
  {
    product: productSchema, 
    quantity: {
      type: Number,
      required: true,
      min: [1, "Quantity can not be less then 1."],
    },
  },
  {
    timestamps: true,
  }
);

const CartSchema = new Schema(
  {
    userID: {
      type: Schema.Types.ObjectId,
      ref: "User",
    },
    items: [cartItemSchema],
  },
  { timestamps: true }
);

module.exports = model<Cart>("Cart", CartSchema);

问题是,当我在特定用户购物车中添加产品时,当同一产品已添加到另一个用户购物车文档时,我收到此错误:

“消息”:“无法添加到购物车 E11000 重复键错误集合:elec-store.carts 索引:items.productID_1 重复键:{ items.productID:null },堆栈:MongoError:E11000 重复键错误集合:elec -store.carts 索引:items.productID_1 复制键

这是添加功能

 public async add(cartItem: CartItem, userID: string): Promise<Cart> {
    let cartInDB = null;

    await CartModel.findOne({ userID: userID }, (err, cart) => {
      cartInDB = cart;
    });

    if (AppUtils.hasValue(cartInDB)) {
      const index = cartInDB.items.findIndex(
        (item) => item.product._id.toString() === cartItem.product._id
      );

      if (index !== -1) {
        cartInDB.items[index].quantity =
          cartInDB.items[index].quantity + cartItem.quantity;
        cartInDB.items[index].product._id = cartItem.product._id;

        const cartAfterAdding = await cartInDB.save();

        return cartAfterAdding;
      } else {
        await CartModel.update(
          { _id: cartInDB._id },
          { $push: { items: cartItem } }
        );
      }

      return cartInDB;
    } else {
      const itemsArray: CartItem[] = [];
      itemsArray.push(cartItem);

      let createdCart = new CartModel({
        userID: userID,
        items: itemsArray,
      });

      await createdCart.save(); \\ this is where the problem occurs


      return createdCart;
    }
  }

这就是我的购物车在 mongodb 文档中的样子:

 db.carts.find().pretty()
{
        "_id" : ObjectId("60ea9fb81b2b4c048c3b1544"),
        "userID" : ObjectId("60dee5e1da81bd274cd304de"),
        "items" : [
                {
                        "_id" : ObjectId("60ea9fb81b2b4c048c3b1545"),
                        "product" : {
                                "_id" : ObjectId("60e62cb21f74572b7c0b3a30"),
                                "name" : "tv",
                                "description" : "the best tv",
                                "categoryID" : 2,
                                "quantity" : "2",
                                "serialNumber" : "226swaq12",
                                "price" : 2000,
                                "imgUrl" : "https://www.seekpng.com/png/full/774-7744281_samsung-electronics-samsung-electronic-product-png.png"
                        },
                        "quantity" : 6,
                        "createdAt" : ISODate("2021-07-11T07:37:29.790Z"),
                        "updatedAt" : ISODate("2021-07-11T07:38:15.583Z")
                },
                {
                        "_id" : ObjectId("60eaa16b1b2b4c048c3b155d"),
                        "product" : {
                                "_id" : ObjectId("60e066009be1060748201ad3"),
                                "name" : "samsung tv",
                                "description" : "the best tv",
                                "quantity" : "2",
                                "categoryID" : 2,
                                "serialNumber" : "2212",
                                "price" : 2000,
                                "imgUrl" : "https://www.seekpng.com/png/full/774-7744281_samsung-electronics-samsung-electronic-product-png.png"
                        },
                        "quantity" : 9,
                        "updatedAt" : ISODate("2021-07-11T07:46:19.313Z"),
                        "createdAt" : ISODate("2021-07-11T07:44:43.764Z")
                }
        ],
        "createdAt" : ISODate("2021-07-11T07:37:29.792Z"),
        "updatedAt" : ISODate("2021-07-11T07:46:19.314Z"),
        "__v" : 0
}

【问题讨论】:

    标签: javascript node.js mongodb mongoose mongoose-schema


    【解决方案1】:

    我使用 mongoose.Schema 创建新的模式,然后在引用不同的模式时,我会这样做:

    product: { type: mongoose.Schema.Types.ObjectId, ref: 'product' },
    

    如果稍后您还需要显示产品信息 (db.carts.find()),您可以使用 populate() 替换所有产品条目的引用。

    【讨论】:

      【解决方案2】:

      你可以使用 upsert true。

        db.collection.update(
       <query>,
       <update>,
       {
        upsert: <boolean>,
        multi: <boolean>,
        writeConcern: <document>,
        collation: <document>,
        arrayFilters: [ <filterdocument1>, ... ],
        hint:  <document|string>        // Available starting in MongoDB 4.2
      }
      )
      

      例如-

            db.books.update(
            { item: "ZZZ135" },   // Query parameter
            {                     // Replacement document
               item: "ZZZ135",
               stock: 5,
               tags: [ "database" ]
            },
            { upsert: true }      // Options
           )
      

      这可能会有所帮助:Mongo Update

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-26
        • 2019-10-17
        • 2021-11-19
        • 2017-08-30
        • 1970-01-01
        • 2019-07-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多