2014-05-21 16 views
10

Khi tạo tài liệu mới và sau đó cố gắng upsert một tiểu tài liệu mới, tôi nhận được lỗi này:lỗi khóa trùng lặp khi tạo một mongoose mới sub-tài liệu

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 

Tiểu tài liệu tôi đang cố gắng để chèn được định nghĩa là lược đồ con có trường groupId với các yêu cầu {unique: true}, {sparse: true}. Phương thức mongoose mà tôi đang sử dụng để thực hiện lệnh upsert là:

User.findByIdAndUpdate(userId, 
         { $push: { 'groups': userUpdate} }, 
         function (err, obj) where userUpdate = { groupId: groupId }. 

Sau khi xóa chỉ mục, lỗi này sẽ không còn xảy ra nữa.

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 
}); 
+0

Bạn có thể mở rộng câu hỏi của mình bằng lược đồ tài liệu và các chỉ mục được sử dụng không? –

+1

Nếu bạn đang cố gắng đảm bảo một người dùng không thể có các nhóm trùng lặp trong 'nhóm', thì điều này sẽ không hoạt động. Xem http://stackoverflow.com/q/13907257/1259510 – JohnnyHK

+0

điều tôi không thể hiểu được là tại sao ** userUpdate này có _id? để đề phòng, chỉ cần xóa thuộc tính _id khỏi obj này trước khi chuyển sang $ push – Taha

Trả lời

0

Các {độc đáo: true} yêu cầu trên các lĩnh vực groupId có nghĩa là không có hai tài liệu trong bộ sưu tập có thể chứa cùng groupId, chứ không phải là những gì bạn dự định, thực thi độc đáo của groupIds trong tài liệu. Bạn có thể làm những gì bạn muốn bằng cách sử dụng toán tử MongoDB $addToSet thay thế.

1

Nếu bạn áp dụng upsert trên mảng đối tượng thì điều này sẽ luôn tạo tài liệu mới vì nó không so sánh tài liệu phụ của mảng và bạn có chỉ mục duy nhất trên groupId để không cho phép bạn tạo bản ghi mới giá trị. Đối với nó, bạn sẽ tìm thấy bản ghi đó và nếu tồn tại, sau đó cập nhật nó khác tạo bản ghi mới.

Cách tốt nhất khác là sử dụng $ addToSet. Hy vọng điều này sẽ hữu ích.

0

Nếu bạn đang cố gắng cập nhật nhóm hiện có từ mảng nhóm, $ push không phải là giải pháp.

User.findAndUpdate({_id:userId,'groups.groupId': userUpdate.groupId}, 
         { $set: {'groups.$': userUpdate}}, 
         function (err, obj){}) 

nếu không như $ addToSet được đề xuất khác sẽ thêm phần tử vào nếu nó tồn tại.

User.findByIdAndUpdate(userId, 
         { $addToSet : { 'groups': userUpdate} }, 
         function (err, obj){}) 
Các vấn đề liên quan