2013-10-02 26 views
5

Muốn upsert trong thuộc tính đối tượng trong một mảng của một tài liệuMongoDB upsert trong việc cập nhật một phần tử mảng

Xem xét một tài liệu trong bộ sưu tập m

{ "_id" : ObjectId("524bfc39e6bed5cc5a9f3a33"), 
"x" : [  
    { "id":0.0, "name":"aaa"},{ "id":1.0, "name":"bbb"} 
] 
} 

Bạn muốn thêm age:100-{ "id":0.0, "name":"aaa"}. Không chỉ là tuổi .. Nhưng mà cung cấp cho upsert trong phần tử mảng {}. Vì vậy, nó có thể chứa {age:100,"city":"amd"} (kể từ khi tôi đang nhận được điều này từ các dịch vụ ứng dụng)

đã cố gắng này ... Nhưng không làm việc vì nó thay thế toàn bộ phần tử mảng

db.m.update({_id:ObjectId("524bfc39e6bed5cc5a9f3a33"), 
    "x" : { 
       "$elemMatch" : { 
         "id" : 0.0 
       } 
}}, 
{ 
     $set : { 
       "x.$" : { 
        "age": 100 
      } 
     } 
}, 
{upsert: true} 
) 

Thay đổi tài liệu để (mà tôi không muốn)

{ "_id" : ObjectId("524bfc39e6bed5cc5a9f3a33"), 
    "x" : [  
     { "age":100},{ "id":1.0, "name":"bbb"} 
    ] 
    } 

Điều này có thể không thay đổi giản đồ.

Trả lời

5
$set : {"x.$" : {"age": 100}} 

x.$ đặt toàn bộ phần tử phù hợp mảng để {age: 100}

này nên làm việc:

db.m.update({_id:ObjectId("524bfc39e6bed5cc5a9f3a33"), 
"x.id": 0.0}, {$set: {"x.$.age": 100 }}); 

Sử dụng elemMatch:

db.test.update({x: {$elemMatch: {id: 1}}},{$set: {"x.$.age": 44}}) 

Lưu ý rằng upsert tùy chọn ở đây, là không cần thiết và sẽ không ork nếu số id không có trong x vì toán tử vị trí $ không hỗ trợ upserting.

+0

Tôi biết điều này hoạt động. Nhưng tôi hỏi liệu db.test.update ({x: {$ elemMatch: {id: 1}}}, {$ set: {"x. $": {"A": 100, "b": 200, "tuổi": 44}}}) sẽ hoạt động? Hoặc một cái gì đó tương tự như công trình. Lưu ý {"a": 100, "b": 200, "tuổi": 44} có thể là đối tượng và giá trị "upsert" trong mục khớp của mảng. – andNn

+0

Có, nhưng nó sẽ ** thay thế ** toàn bộ phần tử được so khớp bằng tài liệu mới: '{" a ": 100," b ": 200," tuổi ": 44}'. Và nó không thể 'upert' giá trị bởi vì một' upsert' được thực hiện chỉ khi một trận đấu không được tìm thấy (một phần tử trong 'x' không hiện diện với' id' được chỉ định). –

+0

>> upsert được thực hiện chỉ khi một trận đấu không được tìm thấy ,, nah! trên các thuộc tính tài liệu phù hợp được cập nhật/chèn vào – andNn

0

Điều này là không thể mà không thay đổi giản đồ. Nếu bạn có thể thay đổi lược đồ để sử dụng một đối tượng để lưu trữ các mục của bạn (chứ không phải là một mảng), bạn có thể làm theo cách tiếp cận mà tôi đã nêu trong this answer.

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