2016-09-01 2 views
0

여기 mongo 쉘에서 업데이트를하려고하는데 문제가 있습니다.MongoDB에서 중첩 배열 업데이트

{ 
"_id" : ObjectId("56cc03c16f4e85f538ef79ae"), 
"contact_id" : NumberLong(1000295524418), 
"gender" : 1, 
"phonetic_gender" : 1, 
"first_name" : "LEANDRO", 
"score" : 44, 
"address" : [ 
    { 
     "address_id" : NumberLong(2634224807), 
     "rank" : 201604.0, 
     "score" : 7.0, 
     "street_type" : "AV", 
     "street_title" : "DA", 
     "street" : "EMILIA DE CASTRO MARTINS", 
     "number" : 34.0, 
     "district" : "JARDIM BELA VISTA", 
     "city" : "GUARULHOS", 
     "state" : "SP", 
     "zip_code" : 7132470.0, 
     "create_date" : ISODate("2014-08-07T00:00:00.000Z"), 
     "update_date" : ISODate("2016-05-03T00:00:00.000Z") 
    }, 
    { 
     "address_id" : NumberLong(2634735566), 
     "rank" : 201410, 
     "score" : 10, 
     "street_type" : "AV", 
     "street_title" : "DA", 
     "street" : "EMILIA DE CASTRO MARTINS", 
     "district" : "JARDIM BELA VISTA", 
     "city" : "GUARULHOS", 
     "state" : "SP", 
     "zip_code" : "07132470", 
     "create_date" : ISODate("2014-08-07T03:00:00.000Z"), 
     "update_date" : ISODate("2014-08-07T03:00:00.000Z") 
    } 
]} 

내 모든 문서를 통해 이동 및 현장 "순위"및 주소 배열에 "점수"의 종류를 업데이트해야합니다

나는 다음과 같은 JSON이있다. 나는 몽고에서이 명령을 실행할 때 오류하지 않습니다,

var total = 0 
var skip = 0 
var total_adress = db.company.count() - skip 
var bulk = db.person.initializeUnorderedBulkOp() 
var person = db.getCollection('Person').find({$and:[ {"contact_id":1000295524418}).addOption(DBQuery.Option.noTimeout).forEach(
function(person){ 
     var contact_id = person.contact_id.valueOf() 
      bulk.find(
       { contact_id: contact_id } 
      ).update(
       { 
        $set: { 
         "address.$.zip_code":"address.zip_code".toString(), 
         "address.$.rank": NumberInt("address.rank"), 
         "address.$.number": "address.number".toString(), 
         "address.$.score": NumberInt("address.score") - 2 
        } 
       } 
      ); 


    if((++total % 1000) === 0){ 
     print("Total person....: " + total_adress) 
     print("Iniciando bulk..: " + Date()) 
     bulk.execute({ w: 0 }) 
     bulk = db.company.initializeUnorderedBulkOp() 
     print("Fim bulk........: " + Date()) 
     print("#############################################################################") 
    } 
}); bulk.execute(); print(total); 

지금 문제가 온다 :

는 내가 뭘 다음 코드를 참조하십시오. 그것은 foreach 내에서 떨어지는 있는지 확인하고 올바르게 필드에서 내 데이터를 검색, 문제는 그냥 업데이 트가 작동하지 않습니다.

감사합니다.

+0

당신은 몇 가지 문제가 있습니다. '$'위치 표시기는 첫 번째 하위 문서와 만 일치합니다 (https://docs.mongodb.com/manual/reference/operator/update/positional/ 참조). 또한, 단일 연산에서 어쨌든 현재 값을 참조하여 필드 값을 업데이트 할 수 없습니다. 먼저 문서를로드하고 기존 값을 캡처 한 다음 다른 명령을 실행하여 문서를 업데이트해야합니다. – jstell

+0

@jstell 나에게 보여줄 수 있습니까? – Jhonathan

답변

1

사람 문서의 주소 키는 문서의 배열입니다. jstell의 의견을 바탕으로 해결책 중 하나는 다음 단계를 수행하는 것입니다.

  • 변수 배열을 array_of_addresses 변수로 복사하십시오.
  • array_of_addresses의 각 문서를 반복하고 필요에 따라 키를 업데이트하십시오.
  • bulk.find.update 파이프 라인에서 새로 업데이트 된 배열 array_of_addresses을 사용하여 address 키 값을 업데이트하십시오.

find()와 대량 업데이트 실행 간의 주소 배열에 대한 모든 업데이트는 덮어 쓸 수 있습니다.

다른 작은 변화도 제안 :

  • getCollection('person') 대신 find 명령 광장/중괄호 누락
  • getCollection('Person')의 : find({$and:[{"contact_id":1000295524418} ]})

    var total = 0; 
    var skip = 0; 
    var bulk = db.person.initializeUnorderedBulkOp(); 
    db.getCollection('person').find({$and:[{"contact_id"1000295524418}]}).addOption(DBQuery.Option.noTimeout).forEach(
    
        function(person){ 
    
        //extract the array into array_of_addresses variable 
        var contact_id = person.contact_id.valueOf(); 
        var array_of_addresses = person.address.valueOf() ; 
    
        //Loop through the array_of_addresses 
        for (var i = 0; i< array_of_addresses.length ; i++) { 
    
        //assign element of array to address variable 
        address = array_of_addresses[i]; 
    
        //DO YOUR MODIFICATIONS HERE. e.g. zipcode 
        zip_code = address.zip_code.valueOf().toString(); 
        address.zip_code = zip_code; 
    
        } 
        //Set the modified array value to address element of the document 
        bulk.find(
         { contact_id: contact_id } 
        ).update(
         { 
          $set: { 
          address : array_of_addresses 
         } 
         } 
    ); 
    }); 
    
    //bulk execute 
    bulk.execute();