2014-09-18 13 views
7

Hãy nói rằng tôi có một giản đồ đơn giản:Mongoose chỉ số duy nhất trên subdocument

var testSchema = new mongoose.Schema({ 
    map: { type: [ mongoose.Schema.Types.Mixed ], default: [] }, 
    ...possibly something else 
}); 

Bây giờ chúng ta hãy đảm bảo rằng cặp (_id, map._id) là duy nhất.

testSchema.index({ _id: 1, 'map._id': 1 }, { unique: true }); 

Kiểm tra nhanh bằng cách sử dụng db.test.getIndexes() cho biết rằng nó đã được tạo.

{ 
    "v" : 1, 
    "unique" : true, 
    "key" : { 
     "_id" : 1, 
     "map._id" : 1 
    }, 
    "name" : "_id_1_map._id_1", 
    "ns" : "test.test", 
    "background" : true, 
    "safe" : null 
} 

Vấn đề là, chỉ mục này bị bỏ qua và tôi có thể dễ dàng tạo nhiều subdocuments với cùng một map._id. Tôi có thể dễ dàng thực hiện truy vấn sau nhiều lần:

db.maps.update({ _id: ObjectId("some valid id") }, { $push: { map: { '_id': 'asd' } } }); 

và kết thúc với sau:

{ 
    "_id": ObjectId("some valid id"), 
    "map": [ 
     { 
      "_id": "asd" 
     }, 
     { 
      "_id": "asd" 
     }, 
     { 
      "_id": "asd" 
     } 
    ] 
} 

gì đang xảy ra ở đây? Tại sao tôi có thể đẩy các phân mục phụ xung đột?

+0

Có thể có hai mặt của http://stackoverflow.com/questions/13907257/validating-uniqueness-of-an-embedded-document-scoped-by-its-parent-in-mongoose – JohnnyHK

+0

Thực tiễn không tốt để sử dụng bất kỳ thứ gì khác so với ObjectId cho '_id'. Tại sao bạn muốn làm điều đó? –

Trả lời

14

câu chuyện dài ngắn: Mongo không hỗ trợ chỉ số duy nhất cho các tài liệu phụ, mặc dù nó cho phép tạo ra chúng ...

+4

... có nghĩa là việc lập chỉ mục duy nhất cho các tài liệu phụ không thể được giải thích trong câu hỏi, và đó là những gì tôi đã viết. –

-3

Đối tượng đầu tiênDữ độ đầu tiên trong mongodb phải là 24. Sau đó, bạn có thể tắt _id và đổi tên _id thành id hoặc những người khác và thử $addToSet. Chúc may mắn.

CoffeeScript dụ:

FromSchema = new Schema(
    source: { type: String, trim: true } 
    version: String 
    { _id: false }//to trun off _id 
) 

VisitorSchema = new Schema(
    id: { type: String, unique: true, trim: true } 
    uids: [ { type: Number, unique: true} ] 
    from: [ FromSchema ] 
) 

//to update 
Visitor.findOneAndUpdate(
    { id: idfa } 
    { $addToSet: { uids: uid, from: { source: source, version: version } } } 
    { upsert: true } 
    (err, visitor) -> 
    //do stuff 
+1

'_id' của tài liệu con không phải là một' ObjectId' khi nó được khai báo thành mảng 'Mixed'. Ngoài ra nó không trả lời câu hỏi. –

11

này đi lên trong google vì vậy tôi nghĩ tôi d thêm một thay thế cho việc sử dụng một chỉ mục để đạt được ràng buộc khóa duy nhất như chức năng trong các tài liệu phụ, hy vọng điều đó là OK.

Tôi không khủng khiếp quen thuộc với Mongoose do đó, nó chỉ là một Mongo console update:

var foo = { _id: 'some value' }; //Your new subdoc here 

db.yourCollection.update(
{ '_id': 'your query here', 'myArray._id': { '$ne': foo._id } }, 
{ '$push': { myArray: { foo } }) 

Với các tài liệu trông như:

{ 
    _id: '...', 
    myArray: [{_id:'your schema here'}, {...}, ...] 
} 

Các phúc chính là bạn đảm bảo cập nhật sẽ không trả lại một tài liệu để cập nhật (tức là phần tìm kiếm) nếu khóa subdocument của bạn đã tồn tại.

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