2014-03-30 125 views
1

嘗試更新Mongo中子文檔數組內的元素時遇到問題。如果我認爲在收集「資源」如何更新Mongodb中子文檔數組中的元素

{ 
    "_id": 1, 
    "resources": [ 
     { 
      "resource_id": 1, 
      "resource_list": ["item1","item2"] 
     }, 
     { 
      "resource_id": 2, 
      "resource_list": ["item4","item3"] 
     } 
    ] 
} 

以下文件我想與"resource_id" = 2

其他值一樣"item5"更新"item4"下面的語句給了我一個錯誤:無法應用的位置操作沒有包含數組的對應查詢字段。

db.resource.update({"resources.resource_id": 2, "resources.resource_list": "item4"}, {$set: {"resources.$.resource_list.$": "item5"}})

任何幫助將得到高度讚賞。

回答

1

位置運算符只能在查詢中使用一次。這是一個限制,有一個改善的開放票:https://jira.mongodb.org/browse/SERVER-831

解決這個問題的另一種方法可能是推動「item5」到數組並拉動「item4」。事情是這樣的:

db.resource.update({ "resources.resource_id": 2, "resources.resource_list": "item4" }, { $pull: { "resources.$.resource_list": "item4" }, $push: { "resources.$.resource_list": "item5" } }) 

然而這是不可能的或者,$pull$push不能在同一領域同一查詢中使用。相關門票:https://jira.mongodb.org/browse/SERVER-1050

我看到兩個解決方案。一個是執行兩個查詢。在第一個查詢,你推「ITEM5」,在第二個查詢你拉「ITEM4」:

db.resource.update({ "resources.resource_id": 2, "resources.resource_list": "item4" }, { $push: { "resources.$.resource_list": "item5" } }); 
db.resource.update({ "resources.resource_id": 2, "resources.resource_list": "item4" }, { $pull: { "resources.$.resource_list": "item4" } }); 

如果你想這樣做在一個查詢,你可以使用蒙戈外殼。事情是這樣的:

db.resource.find({ 'resources.resource_id': 2, 'resources.resource_list': 'item4' }).forEach(function(document) { 
    for (var i in document.resources) { 
    if (document.resources[i].resource_id == 2) { 
     var index = document.resources[i].resource_list.indexOf('item4'); 
     document.resources[i].resource_list[index] = 'item5'; 
     db.resource.save(document); 
    } 
    } 
}) 
+0

感謝Gergo對這個您迴應允許的。這非常有幫助,爲了避免對此操作的多個聲明,我稍微改變了我的模型。再次感謝您對此的幫助 – user3315068

0

符號$僅修改搜索最後一個數組的最後位置,並且可以使用$addToSet$push用於新增項目

> db.resource.find() 
    { "_id" : 1, 
     "resources" : [ 
        { "resource_id" : 1, 
         "resource_list" : [ "item1","item2" ] },  
        { "resource_id" : 2, 
         "resource_list" : [ "item4", "item3" ] } ] } 

    > db.resource.update({"resources.resource_id": 2, 
          "resources.resource_list": "item4"}, 
         {$addToSet:{"resources.$.resource_list": "item5"}}) 

    > db.resource.find() 
    { "_id" : 1, "resources" : [ 
          { "resource_id" : 1, 
           "resource_list" : [ "item1", "item2" ] }, 
          { "resource_id" : 2, 
           "resource_list" : [ "item4", "item3", "item5" ] } ] } 

    > db.resource.update({"resources.resource_id": 2, 
          "resources.resource_list": "item4"}, 
         {$pull: {"resources.$.resource_list": "item4"}}) 

    > db.resource.find() 
    { "_id" : 1, "resources" : [ 
           { "resource_id" : 1, 
           "resource_list" : [ "item1", "item2" ] }, 
           { "resource_id" : 2, 
           "resource_list" : [ "item3","item5" ] } ] } 

不過是更好的運行兩個查詢在同一時間?

> db.algo.update({"resources.resource_id": 2, 
        "resources.resource_list": "item4"}, 
       {$addToSet:{"resources.$.resource_list": "item5"}, 
        $pull: {"resources.$.resource_list": "item4"}}) 

字段名稱不能重複使用修改

+0

感謝Carlos對您的迴應,我沒有嘗試使用$ addToSet,但在相同的查詢中嘗試了$ push和$ pull,但沒有奏效。你是說,而不是$推,如果我使用$ addToSet那麼它應該工作? – user3315068

+0

不,MongoDB表示**「修改器不允許的字段名稱重複」**,簡而言之,MongoDB不允許在同一字段中同時查詢刪除和添加值。 –

相關問題