2014-03-30 4 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

두 가지 해결책이 있습니다. 하나는 두 개의 쿼리를 실행하는 것입니다. 첫 번째 쿼리에서는 두 번째 쿼리에 당신이 "item4을"풀 "item5"푸시 : 당신이 한 쿼리에서 그것을 할 경우

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

감사 게르에 사용할 수 없습니다. 이 작업에 대한 하나 이상의 진술을 피하기 위해이 모델을 조금 변경했습니다. 이 도움에 다시 한번 감사드립니다 – 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

귀하의 회신에 감사드립니다, 나는 $ addToSet을 시도하지 않았지만 같은 쿼리에서 $ push와 $ pull을 시도했지만 작동하지 않았습니다. $ addToSet을 사용하면 $ push 대신에 작동해야한다고 말하고 있습니까? – user3315068

+0

아니요, MongoDB는 ** "수정 자와 함께 필드 이름 중복이 허용되지 않습니다"** 즉, MongoDB는 같은 필드에서 동일한 문의에서 삭제를 허용하고 값을 추가 할 수 없습니다. –

관련 문제