2014-03-30 134 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不允许在同一字段中同时查询删除和添加值。 –

相关问题