2010-08-12 69 views
6

我知道這個問題之前已經被問過,但那是一個不同的場景。 我想有一個集合是這樣的:有沒有辦法用單個查詢插入列表?

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

我想要做的是一個UPSERT「論壇」項目,增加櫃檯或者如果它不存在添加的項目。

例如做這樣的事情(我希望這是有道理的):

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

,並具有:

{ 
    "_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, 
    }] 
} 

我一定能夠使它在三個步驟:

  1. 用一個新項目插入整個集合
  2. addToSet論壇項目到列表
  3. 增量論壇項目計數器與位置操作

這就是說:

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}}) 

你知道的更有效的方式來做到這一點? TIA,Germano的

回答

10

您可能已經發現,該positional operator不能在upserts使用:

的位置操作者不能與upsert,因爲它需要一個匹配的數組元素進行組合。如果您的更新導致插入,那麼「$」將被字面上用作字段名稱。

因此,您將無法在單個查詢中實現所需的結果。

已將從計數器更新中分離出文檔的創建。你自己的解決方案是正確的。它可以被壓縮成以下兩個查詢:

// 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

是的,我想通了。不管怎麼說,還是要謝謝你。 – Germano 2010-11-05 10:28:30

相關問題