2010-08-12 22 views
6

Tôi biết câu hỏi này đã được hỏi trước đây, nhưng đó là một kịch bản khác. Tôi muốn có một bộ sưu tập như thế này:Có cách nào để tăng danh sách với một truy vấn không?

{ 
    "_id" : ObjectId("4c28f62cbf8544c60506f11d"), 
    "pk": 1, 
    "forums": [{ 
     "pk": 1, 
     "thread_count": 10, 
     "post_count": 20, 
    }, { 
     "pk": 2, 
     "thread_count": 5, 
     "post_count": 24, 
    }] 
} 

Những gì tôi muốn làm là để upsert một "diễn đàn" mục, incrementing quầy hoặc thêm một mục nếu nó không tồn tại.

Ví dụ để làm một cái gì đó như thế này (Tôi hy vọng nó có ý nghĩa):

db.mycollection.update({ 
    "pk": 3, 
    "forums.pk": 2 
}, { 
    "$inc": {"forums.$.thread_count": 1}, 
    "$inc": {"forums.$.post_count": 1}, 
}, true) 

và có:

{ 
    "_id" : ObjectId("4c28f62cbf8544c60506f11d"), 
    "pk": 1, 
    "forums": [{ 
     "pk": 1, 
     "thread_count": 10, 
     "post_count": 20, 
    }, { 
     "pk": 2, 
     "thread_count": 5, 
     "post_count": 24, 
    }] 
}, 
{ 
    "_id" : ObjectId("4c28f62cbf8544c60506f11e"), 
    "pk": 3, 
    "forums": [{ 
     "pk": 2, 
     "thread_count": 1, 
     "post_count": 1, 
    }] 
} 

tôi chắc chắn có thể làm cho nó trong ba bước:

  1. Tăng toàn bộ bộ sưu tập bằng một mục mới
  2. addToĐặt mục diễn đàn vào danh sách
  3. quầy
  4. increment mục diễn đàn với nhà điều hành theo vị trí

Đó là để nói:

db.mycollection.update({pk:3}, {pk:3}, true) 
db.mycollection.update({pk:3}, {$addToSet: {forums: {pk:2}}}) 
db.mycollection.update({pk:3, 'forums.pk': 2}, {$inc: {'forums.$.thread_counter': 1, {'forums.$.post_counter': 1}}) 

Bạn có biết một cách hiệu quả hơn để làm điều đó? TIA, Germano

Trả lời

10

Như bạn có thể phát hiện, positional operator không thể được sử dụng trong upserts:

Nhà điều hành theo vị trí không thể được kết hợp với một upsert vì nó đòi hỏi một phần tử mảng phù hợp. Nếu bản cập nhật của bạn dẫn đến chèn thì chữ "$" theo nghĩa đen sẽ được sử dụng làm tên trường.

Vì vậy, bạn sẽ không thể đạt được kết quả mong muốn trong một truy vấn.

Bạn để tách riêng việc tạo tài liệu khỏi bản cập nhật bộ đếm. Giải pháp của riêng bạn đang đi đúng hướng. Nó có thể được cô đặc thành hai truy vấn sau:

// optionally create the document, including the array 
db.mycollection.update({pk:3}, {$addToSet: {forums: {pk:2}}}, true) 

// update the counters in the array item 
db.mycollection.update({pk:3, 'forums.pk': 2}, {$inc: {'forums.$.thread_counter': 1, 'forums.$.post_counter': 1}}) 
+0

Vâng, tôi đã hiểu điều đó. Dù sao cũng cảm ơn bạn. – Germano

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