2013-04-10 35 views
19

Đối với dự án của tôi, tôi muốn giữ một tài liệu mongoose cho các nhóm của các tổ chức, như thế này:giá trị Mongoose độc ​​đáo trong mảng lồng nhau của các đối tượng

var groupSchema = Schema({ 
    name : { type : String }, 
    org : { type : Schema.Types.ObjectId, ref : 'Organization' }, 
    ... 
    users : [{ 
    uid : { type : Schema.Types.ObjectId, ref : 'User' }, 
    ... 
    }] 
}); 

tôi muốn ngăn chặn người sử dụng cùng một từ là trong cùng một nhóm hai lần. Để làm điều này, tôi cần phải ép buộc users.uid là duy nhất trong mảng người dùng. Tôi đã thử nói 'độc đáo: đúng' cho uid, nhưng điều đó không hiệu quả. Có cách nào để làm điều này với mongoose hoặc mongoDB mà không cần truy vấn thêm hoặc tách lược đồ?

Edit: tôi đã thay đổi giá trị trước đó của uid để uid: {type: Schema.Types.ObjectId, ref: 'Người dùng', chỉ số: {độc đáo: đúng, dropDups: true}} Nhưng điều này vẫn doesn dường như không hoạt động.

Chỉnh sửa: Giả sử không có cách đơn giản để đạt được điều này, tôi đã thêm một truy vấn bổ sung kiểm tra xem người dùng đã có trong nhóm chưa. Điều này dường như với tôi cách đơn giản nhất.

+0

kiểm tra điều này sẽ hữu ích (http://stackoverflow.com/questions/12395118/mongodb-setting-unique-field) – karthick

+0

Cảm ơn bạn đã liên kết. Tôi đã thử như sau: uid: {type: Schema.Types.ObjectId, ref: 'Người dùng', chỉ mục: {unique: true, dropDups: true}} thay vì giá trị cũ cho uid. Điều này vẫn không hoạt động, tôi cũng đã cố gắng khởi động lại mongoDB mà không thành công. –

Trả lời

61

Một chỉ mục duy nhất trên trường mảng thực thi rằng cùng một giá trị không thể xuất hiện trong các mảng của nhiều tài liệu trong bộ sưu tập, nhưng không ngăn cùng một giá trị xuất hiện nhiều lần trong một mảng của tài liệu . Vì vậy, bạn cần phải đảm bảo tính duy nhất khi bạn thêm các phần tử vào mảng thay thế.

Sử dụng toán tử $addToSet để chỉ thêm giá trị vào một mảng nếu giá trị chưa có.

Group.update({name: 'admin'}, {$addToSet: {users: userOid}}, ... 

Tuy nhiên, nếu mảng users chứa các đối tượng với nhiều thuộc tính và bạn muốn đảm bảo tính độc đáo trên chỉ là một trong số họ (uid trong trường hợp này), sau đó bạn cần phải có cách tiếp cận khác:

var user = { uid: userOid, ... }; 
Group.update(
    {name: 'admin', 'users.uid': {$ne: user.uid}}, 
    {$push: {users: user}}, 
    function(err, numAffected) { ... }); 

Điều đó làm là đủ điều kiện cập nhật $push chỉ xảy ra nếu user.uid không tồn tại trong trường uid của bất kỳ phần tử nào trong số users. Vì vậy, nó bắt chước hành vi $addToSet, nhưng chỉ với uid.

+0

Nhưng làm thế nào bạn có thể buộc chỉ uid là duy nhất? Trong mảng người dùng, tôi có nhiều thuộc tính có thể khác nhau mỗi lần tôi thêm cùng một người dùng (như ngày). –

+0

Cảm ơn bạn đã nhập. Tôi đã đọc về trình duyệt tính hợp lệ nhưng tôi không thấy cách dễ dàng hơn việc thêm truy vấn bổ sung kiểm tra xem người dùng đã có trong nhóm hay chưa. –

+0

@GuidoPassage Tôi đã thêm một cách để hỗ trợ trường hợp sử dụng cụ thể của bạn. – JohnnyHK

Các vấn đề liên quan