2013-03-05 2 views
2

MongoDB를 사용하면서로드 블록을 실행 한 것으로 보입니다. 내 데이터베이스 구조를 수정하지 않고도 주변에 어쨌든 있는지 여부를 알고 싶습니다. 내가 속성의 특정 tag_ids를 업데이트하는 방법을 알아낼 수없는 문제로 실행하고서브 그룹의 몽고 업데이트

Company= 
{ 
    _id:1, 
    properties:[ 
     { 
      property_id: 1 
      tags : [ 
      { 
       tag_id: 1 
       tag_value: 1000 
       channels: [ 
         { 
          channel_id:1 
          channel_name:"test1" 
         }, 
         { 
          channel_id:2 
          channel_name:"test2" 
         }] 
      }, 
      { 
       tag_id:2 
       tag_value: 2500 
       channels: [ 
         { 
          channel_id:2 
          channel_name:"test2" 
         }, 
         { 
          channel_id:3 
          channel_name:"test3" 
         }] 

      }] 
     }, 
     { 
      property_id: 2 
      tags : [ 
      { 
       tag_id: 3 
       tag_value: 500 
       channels: [ 
         { 
          channel_id:1 
          channel_name:"test1" 
         }, 
         { 
          channel_id:3 
          channel_name:"test3" 
         }] 
      }, 
      { 
       tag_id: 4 
       tag_value: 5000 
       channels: [ 
         { 
          channel_id:1 
          channel_name:"test1" 
         }]      
      }] 
     }]  
} 

다음과 같이 지금 내 데이터베이스 구조입니다. 예를 들어, 속성 2의 tag_id 4 값을 100으로 변경하고 싶습니다. 또는 tag_id 3의 채널 배열에 채널을 추가하려고합니다.

무엇을하고 싶은지는 다음과 같습니다.

db.company.update({_id:1, "properties.property_id":2, "tags.tag_id":4}, {"properties.$.tags.$.tag_value":100}); 

그러나 현재 MongoDB의 현재 버전에서는 지원되지 않으며 이미 JIRA에 있습니다. 그래서 내 질문에 어쨌든 당신이 그것을 액세스하기 위해 두 가지 조건을 지정해야하는 문서의 가치를 업데이 트하는 것입니다. 나는 properties.1.tags.0을 할 수 있다는 것을 알고 있습니다. 그러나 배열의 순서를 알 수는 없으며 질의는 프로그래밍 방식으로 실행됩니다.

어떤 도움도 좋을 것입니다. 심지어 테이블을 재구성해야하는 구조입니다.

때문에 (모든 레벨이) 모든 내부 배열의 외부 요소의 모든 데이터를 반복하는 요소에 대해, 당신은

+2

업데이트 어레이 배열에 중첩하여 MongoDB 불량지지를 받고; 필자가 언급 한 것처럼 수치 인덱스를 지정하지 않고는 아무 것도 할 수 없다. 가장 좋은 방법은 스키마를 재사용/병합하여 스키마를 방지하는 것입니다. – JohnnyHK

+0

그게 내가 생각한대로, MongoDB가 중첩 된 문서에 대한 지원을 곧 증가시킬 수 있기를 바랍니다. – Eumcoz

답변

1

배열이 오히려 큰 문서로 이어질 수 평평 감사드립니다. 패턴 화 된 옵션이 없으면 언급 락스에서 향상된 기능 (SERVER-831)을 기다리는 동안

따라서, 여기서 해결책은 :

  • 배열을 조작 변수
  • 에 문서를 판독

귀하의 사례를 감안할 때 전체 배열을 재 작성, 문서를 업데이트이 같을 것이다 :

,451,515,
doc = db.xx.findOne({_id:1}); 
doc.properties.forEach(function(p) { 
    if (p.property_id == 2) { 
     p.tags.forEach(function(t) { 
      if (t.tag_id == 3) { 
       t.tag_value = 100; 
      } 
      else if (t.tag_id == 4) { 
       newChannel = {}; 
       newChannel.channel_id = 5; 
       newChannel.channel_name = "test5"; 
       t.channels.push(newChannel); 
      } 
     }) 
    } 
}); 
db.xx.update({_id:1},{$set:{properties:doc.properties}}); 

결과가 :

doc = db.xx.findOne({_id:1}) 
{ 
    "_id" : 1, 
    "properties" : [ 
     { 
      "property_id" : 1, 
      "tags" : [ 
       { 
        "tag_id" : 1, 
        "tag_value" : 1000, 
        "channels" : [ 
         { 
          "channel_id" : 1, 
          "channel_name" : "test1" 
         }, 
         { 
          "channel_id" : 2, 
          "channel_name" : "test2" 
         } 
        ] 
       }, 
       { 
        "tag_id" : 2, 
        "tag_value" : 2500, 
        "channels" : [ 
         { 
          "channel_id" : 2, 
          "channel_name" : "test2" 
         }, 
         { 
          "channel_id" : 3, 
          "channel_name" : "test3" 
         } 
        ] 
       } 
      ] 
     }, 
     { 
      "property_id" : 2, 
      "tags" : [ 
       { 
        "tag_id" : 3, 
        "tag_value" : 100, 
        "channels" : [ 
         { 
          "channel_id" : 1, 
          "channel_name" : "test1" 
         }, 
         { 
          "channel_id" : 3, 
          "channel_name" : "test3" 
         } 
        ] 
       }, 
       { 
        "tag_id" : 4, 
        "tag_value" : 5000, 
        "channels" : [ 
         { 
          "channel_id" : 1, 
          "channel_name" : "test1" 
         }, 
         { 
          "channel_id" : 5, 
          "channel_name" : "test5" 
         } 
        ] 
       } 
      ] 
     } 
    ] 
} 
+0

임시로 DB를 재구성 할 수 있었으며 관계형 모델로 만들었습니다. (나는 몽고에서하는 것을 싫어하지만 그것을 작동시켜야했습니다.) 위의 구조를 사용해야 할 때 JIRA 티켓이 해결 될 것이라고 기대하고 있습니다. 마지막 업데이트는 2.6에서 발생하기를 희망합니다. 그렇지 않다면 솔루션은 실행 가능한 솔루션처럼 보입니다. 아마도 이것이 현재 가장 좋은 선택 일 것입니다. – Eumcoz

관련 문제