Дублирующая ключевая ошибка при создании нового субдокума мангуста

При создании нового документа, а затем попытайтесь обновить новый суб-документ, я получаю эту ошибку:

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){})