如何避免mongodb中的重复键错误收集
Posted
技术标签:
【中文标题】如何避免mongodb中的重复键错误收集【英文标题】:how to avoid duplicate key error collection in 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
【问题讨论】:
【参考方案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
【讨论】:
以上是关于如何避免mongodb中的重复键错误收集的主要内容,如果未能解决你的问题,请参考以下文章
使用空数组添加新用户记录时出现“E11000 重复键错误收集”
E11000 重复键错误收集 info.subs: null
E11000 重复键错误收集:ad-network.users 索引:username_1 重复键: : null
在 mongo 中插入 doc 时 E11000 重复键错误收集
E11000 重复键错误收集:db.products 索引:product_id_1 重复键: product_id:null