복붙노트

[MONGODB] 어떻게 몽고 문서에 중첩 된 필드의 데이터 유형을 변경하려면?

MONGODB

어떻게 몽고 문서에 중첩 된 필드의 데이터 유형을 변경하려면?

내 몽고 구조 아래로,

"topProcesses" : [
        {
            "cpuUtilizationPercent" : "0.0",
            "processId" : "1",
            "memoryUtilizationPercent" : "0.1",
            "command" : "init",
            "user" : "root"
        },
        {
            "cpuUtilizationPercent" : "0.0",
            "processId" : "2",
            "memoryUtilizationPercent" : "0.0",
            "command" : "kthreadd",
            "user" : "root"
        },
        {
            "cpuUtilizationPercent" : "0.0",
            "processId" : "3",
            "memoryUtilizationPercent" : "0.0",
            "command" : "ksoftirqd/0",
            "user" : "root"
        },
        {
            "cpuUtilizationPercent" : "0.0",
            "processId" : "5",
            "memoryUtilizationPercent" : "0.0",
            "command" : "kworker/0:+",
            "user" : "root"
        },
        {
            "cpuUtilizationPercent" : "0.0",
            "processId" : "6",
            "memoryUtilizationPercent" : "0.0",
            "command" : "kworker/u3+",
            "user" : "root"
        },
        {
            "cpuUtilizationPercent" : "0.0",
            "processId" : "8",
            "memoryUtilizationPercent" : "0.0",
            "command" : "rcu_sched",
            "user" : "root"
        } 
    ]

이제 문서 위에 topProcesses.cpuUtilizationPercent 문자열에 내가 플로트에 topProcesses.cpuUtilizationPercent 데이터 형식 변경을 원했습니다. 이를 위해 나는 다음 시도했지만이 일을하지 않았다

db.collectionName.find({
   "topProcesses":{"$exists":true}}).forEach(function(data){
    for(var ii=0;ii<data.topProcesses.length;ii++){
   db.collectionName.update({_id: data._id},{$set:{"topProcesses.$.cpuUtilizationPercent":parseFloat(data.topProcesses[ii].cpuUtilizationPercent)}},false,true);
  }
})

어떻게 변경된 문자열에 대한 하나의 도움이 중첩 된 몽고 문서에 부유하는 수

해결법

  1. ==============================

    1.당신이 올바른 방법으로 일을하지만 당신은 .update를 쿼리 부분 ()에서 일치하는 배열 요소를 포함하지 않았다 :

    당신이 올바른 방법으로 일을하지만 당신은 .update를 쿼리 부분 ()에서 일치하는 배열 요소를 포함하지 않았다 :

    db.collectionName.find({
       "topProcesses":{"$exists":true}}).forEach(function(data){
        for(var ii=0;ii<data.topProcesses.length;ii++) {
          db.collectionName.update(
             { 
                 "_id": data._id, 
                 "topProcesses.processId": data.topProcesses[ii].processId // corrected
             },
             {
                 "$set": {
                   "topProcesses.$.cpuUtilizationPercent":
                       parseFloat(data.topProcesses[ii].cpuUtilizationPercent)
                 }
             }
          );
      }
    })
    

    그래서 당신은 어떤 효과가 위치 $ 연산자의 순서를 배열에 뭔가를 일치해야합니다.

    어쨌든 루프에서 그 생산되기 때문에 당신은 또한 그냥 표기에서 "인덱스"값을 사용 할 수 :

    db.collectionName.find({
       "topProcesses":{"$exists":true}}).forEach(function(data){
        for(var ii=0;ii<data.topProcesses.length;ii++) {
    
          var updoc =  { 
              "$set": {}
          };
    
          var myKey = "topProcesses." + ii + ".cpuUtilizationPercent";
          updoc["$set"][myKey] = parseFloat(data.topProcesses[ii].cpuUtilizationPercent);
    
          db.collectionName.update(
             { 
                 "_id": data._id
             },
             updoc
          );
      }
    })
    

    이는 단지 매칭 인덱스를 사용하고, 배열 요소에는 고유 ID가없는 경우 유용하다.

    또한 "upsert"또는 "다"옵션도 때문에이 문서를 기존의 프로세스 방법의 특성으로 여기에 적용해야 있습니다.

    그냥이에 "추신"참고로, 2.6 이상에서 버전에서 MongoDB를의 대량 작업 API를 고려하는 것도 가치가있다. 이러한 API 방법을 사용하면 크게 클라이언트 응용 프로그램과 데이터베이스 사이의 네트워크 트래픽의 양을 줄일 수 있습니다. 여기에 확실한 개선은 전반적인 속도에있다 :

    var bulk = db.collectionName.initializeOrderedBulkOp();
    var counter = 0;
    
    db.collectionName.find({
       "topProcesses":{"$exists":true}}
    ).forEach(function(data){
        for(var ii=0;ii<data.topProcesses.length;ii++) {
    
          var updoc =  { 
              "$set": {}
          };
    
          var myKey = "topProcesses." + ii + ".cpuUtilizationPercent";
          updoc["$set"][myKey] = parseFloat(data.topProcesses[ii].cpuUtilizationPercent);
    
          // queue the update
          bulk.find({ "_id": data._id }).update(updoc);
          counter++;
    
          // Drain and re-initialize every 1000 update statements
          if ( counter % 1000 == 0 ) {
              bulk.execute();
              bulk = db.collectionName.initializeOrderedBulkOp();
          }
      }
    })
    
    // Add the rest in the queue
    if ( counter % 1000 != 0 )
        bulk.execute();
    

    이것은 기본적으로 매 1000 개 대기중인 작업을 한 번 전송로 단절로 전송 작업 문의 양을 줄일 수 있습니다. 당신은 번호와 어떻게 일이 그룹화되어 함께 플레이 할 수 있지만, 상대적으로 안전한 방법으로 속도의 상당한 증가를 줄 것이다.

  2. ==============================

    2.당신은 float로 문자열에서 topProcesses.cpuUtilizationPercent의 업데이트 데이터 형 쿼리 아래에 사용할 수 있습니다

    당신은 float로 문자열에서 topProcesses.cpuUtilizationPercent의 업데이트 데이터 형 쿼리 아래에 사용할 수 있습니다

    db.db.find({"topProcesses.cpuUtilizationPercent" : {$exists : true}}).
    forEach( function(obj)
    { obj.topProcesses.cpuUtilizationPercent = new ISODate(obj.topProcesses.cpuUtilizationPercent);
    db.db.save(obj); } );
    
  3. from https://stackoverflow.com/questions/27498872/how-to-change-datatype-of-nested-field-in-mongo-document by cc-by-sa and MIT license