Дублирующая ключевая ошибка при создании нового субдокума мангуста
При создании нового документа, а затем попытайтесь обновить новый суб-документ, я получаю эту ошибку:
Object {error: "E11000 duplicate key error index: sales.users.$gro…p key:
{ : ObjectId('537b7788da19c4601d061d04') }"}
error: "E11000 duplicate key error index: sales.users.$groups.groupId_1
dup key: { : ObjectId('537b7788da19c4601d061d04') }"
__proto__: Object
Поддокумент, который я пытаюсь вставить, определяется как подсхема с полем groupId с требованиями {unique: true}, {sparse: true}. Метод вызова mongoose, который я использую, чтобы выполнить upsert:
User.findByIdAndUpdate(userId,
{ $push: { 'groups': userUpdate} },
function (err, obj) where userUpdate = { groupId: groupId }.
После удаления индексов проблема исправлена, и эта ошибка больше не возникает.
var UserSchema = new Schema({
email: {
type: String,
required: true,
unique: true
},
active: {
type: Boolean,
default: true
},
username: {
type: String,
required: true,
unique: true
},
password: {
salt: {
type: String,
required: true
},
hash: {
type: String,
required: true
}
},
securityQuestion: {
question: String,
salt: String,
hash: String
},
mobile: {
PIN: Number,
Number: Number
},
createDate: {
type: Date,
default: Date.now
},
updateDate: Date,
lastLoginDate: Date,
prevLoginDate: Date,
passChangeDate: Date,
locked: Boolean,
lockDate: Date,
failedCount: Number,
failedDate: Date,
profile: profile,
preference: preference,
courses: [UserCourseSchema],
groups: [UserGroupSchema],
rewards: [UserRewardSchema],
roles: UserRoleSchema,
scores: [UserScoreSchema]
});
var UserGroupSchema = new Schema({
groupId: {
type: Schema.Types.ObjectId,
unique: true,
sparse: true
},
joinDate: {
type: Date,
default: Date.now
},
receiveNotifications: {
type: Boolean,
default: true
},
isAdmin: {
type: Boolean,
default: false
},
isOwner: {
type: Boolean,
default: false
},
isModerator: {
type: Boolean,
default: false
},
updateDate: Date
});
Ответы
Ответ 1
Если вы применяете upsert в массиве объектов, тогда это всегда будет создавать новый документ, поскольку он не сравнивает вспомогательные документы массива и у вас есть уникальный индекс для groupId, поэтому он не позволяет вам создавать новую запись с тем же значением, Для этого вы должны найти эту запись и, если она существует, а затем обновить ее, создайте новую запись.
Еще один лучший способ - использовать $addToSet.
Надеюсь, это поможет.
Ответ 2
Требование {unique: true} в поле groupId означает, что никакие два документа в коллекции не могут содержать один и тот же идентификатор groupId, а не то, что вы намеревались, чтобы обеспечить уникальность идентификаторов group внутри документа. Вы можете сделать то, что хотите, используя вместо этого оператор MongoDB $addToSet.
Ответ 3
Если вы пытаетесь обновить существующую группу из массива групп, $push не является решением.
User.findAndUpdate({_id:userId,'groups.groupId': userUpdate.groupId},
{ $set: {'groups.$': userUpdate}},
function (err, obj){})
в противном случае, поскольку другой предложенный $addToSet добавит элемент в набор, если он существует.
User.findByIdAndUpdate(userId,
{ $addToSet : { 'groups': userUpdate} },
function (err, obj){})