E11000 MongoDB/Mongoose 重复键错误
Posted
技术标签:
【中文标题】E11000 MongoDB/Mongoose 重复键错误【英文标题】:E11000 duplicate key error with MongoDB/Mongoose 【发布时间】:2018-10-12 00:09:39 【问题描述】:我有一个用户模型架构、一个工作模型架构和一个评论模型架构。这些架构之间的关系是用户可以提交许多作品(如博客文章),并且可以评论/评论(我们称之为评论)其他人的帖子(作品)。
因此,当用户提交评论(将其视为评论)时,这就是我的发帖路线。我通过 id 找到工作,然后创建一个新的批评模型对象,并将其传递给 .create() mongoose 函数。一切似乎都很顺利,直到我点击foundWork.critiques.push(createdCritique)
行。控制台日志错误说:
BulkWriteError: E11000 重复键错误集合:zapper.critiques index: username_1 dup key: : null
显然,对象中有两个用户名键并且它们相互冲突,但我对此还不够熟悉,无法找到问题的根源并在 mongoose 模型中修复它。型号如下。如果有人可以提供帮助,将不胜感激。
// post route for getting the review
router.post('/:id', isLoggedIn, function(req, res)
Work.findById(req.params.id, function(err, foundWork)
if (err)
console.log(err);
else
// create a new critique
var newCritique = new Critique (
reviewerName:
id: req.user._id,
username: req.user.username
,
work:
id: foundWork._id,
title: foundWork.title
,
critique : req.body.critique,
date: Date.now(),
rating: 0
);
// save new critique to db
Critique.create(newCritique, function(err, createdCritique)
if (err)
console.log(err)
else
console.log("Created critique is ");
console.log(createdCritique);
// push the new critique into array of critiques of the work
foundWork.critiques.push(createdCritique);
// save to db
foundWork.save();
);
);
用户模型:
var mongoose = require('mongoose');
var passportLocalMongoose = require('passport-local-mongoose');
var UserSchema = new mongoose.Schema(
firstname: String,
lastname: String,
username: String,
password: String,
email: String,
zip: String,
bio:
type: String,
default: ''
,
influences:
type: String,
default: ''
,
favBooks:
type: String,
default: ''
,
notWriting:
type: String,
default: ''
,
favHero:
type: String,
default: ''
,
favVillain:
type: String,
default: ''
,
works: [
type: mongoose.Schema.Types.ObjectId,
ref: 'Work'
],
critiques: [
type: mongoose.Schema.Types.ObjectId,
ref: 'Critique'
],
friends: [
friendId: String,
friendName : String,
friendPic: String
],
friendRequests: [
sendingFriendId: String,
sendingFriendName : String,
sendingFriendPic: String
],
createdDate:
type: Date,
default: Date.now
,
lastLogin:
type: Date,
default: Date.now
);
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
工作模式:
var mongoose = require('mongoose');
var WorkSchema = new mongoose.Schema(
title: String,
genre: String,
workType: String,
length: Number,
ageRange: String,
author:
id:
type: mongoose.Schema.Types.ObjectId,
ref: "User"
,
username: String
,
manuscriptText: String,
critiques: [
id:
type: mongoose.Schema.Types.ObjectId,
ref: "Critique"
],
ratingNumber: [Number],
ratingSum:
type: Number,
default: 0
,
date:
type: Date,
default: Date.now
,
isPublic:
type: Boolean,
default: true
);
module.exports = mongoose.model("Work", WorkSchema);
批评模型:
var mongoose = require('mongoose');
var passportLocalMongoose = require('passport-local-mongoose');
var CritiqueSchema = new mongoose.Schema(
reviewerName:
id:
type: mongoose.Schema.Types.ObjectId,
ref: "User"
,
username: String
,
work:
id:
type: mongoose.Schema.Types.ObjectId,
ref: "Work"
,
title: String
,
critique: String,
date:
type: Date,
default: Date.now
,
rating: [Number]
);
CritiqueSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("Critique", CritiqueSchema);
【问题讨论】:
【参考方案1】:当您在 MongoDB 中创建唯一索引时,默认行为是它也会索引空值。
这意味着如果您的集合中有一个用户名为 null 的文档,则不能添加另一个用户名为 null 的文档。
您需要的是 a sparse index,它只索引实际值(并忽略该字段为 null 的文档)。
Check this link 它展示了如何在 mongoose 中创建稀疏索引与“正常”索引(索引:true,vs 备用:true)。大多数时候,您需要稀疏索引。
【讨论】:
以上是关于E11000 MongoDB/Mongoose 重复键错误的主要内容,如果未能解决你的问题,请参考以下文章
E11000 mongodb mongoose 中的重复键错误索引
E11000 mongodb mongoose 中的重复键错误索引