2016년 2월 19일 금요일

[nodejs] MongoDB Read > Process > Update 실전 코드

요구사항 : MongoDB 의 한 Collection 에서 field A 가 비어져 있는 Document를 찾아서
field B를 바탕으로 field A를 계산한 다음에 field A 업데이트 시키기.

Step 1 : MongoDB 접속 코드 준비

var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/test';

MongoClient.connect(url, function(err, db) {
     read(db, process);
})


접속 후, read  라는 함수를 호출한다. read라는 함수는 자기 작업이 끝나면 process라는
함수를 호출한다.

Step 2 : read함수 구현 - db에서 Document읽어서 배열 채우기

var read = function(db, next) {
        var finddoc = { fieldA : /^$/ };
        var cursor = db.collection('collname').find( finddoc ).limit(500); 
        var arr = []; 
        cursor.each( function(err, doc) {
                if (doc != null) {
                        arr.push(doc);
                }
                else {
                        next(arr, 0, db);
                }   
        }
}

'collname'이라는 collection 에서 finddoc에 정의한 문서 즉, fieldA가 비어져 있는 문서를
찾는다.

일단은 arr이라는 배열에 검색한 모든 문서를 넣는다.

여기서 find할때 limit(500)을 줘서 메모리 관리를 하였다...

몇 천건을 수행하니 프로그램이 뻗었다.

Step 3 : process함수 구현 - 배열 순회하면서 처리하기

var process = function (arr, i, db) {
       if (i < arr. length) {
                processImpl(arr[i], db, function() {
                     process(arr, i+1, db);
               });
      } 
      else {
           db.close();
      }
}

arr에 저장된 Document를 sync하게 처리해주기 위해서 process 는 재귀적으로 자신을 호출하며
그 안에서processImpl을 호출한다.

실제 각 Document 에 대해 해줘야 하는 일들은 processImpl함수에다가 구현을 한다.

Step 4 : processImpl함수 구현 - 각 배열의 요소 처리 


var processImpl(doc, db, next) {
    var fieldB = doc['fieldB'];
    var fieldA = fieldA + 10;
    db.collection('collectionName').update(
              {'fieldB':fieldB}, 
              {$set : {'fieldA' : fieldA}}, 
              function() {
                   next();
              }
    );
}

db 에 update 가 완료되어야 그 다음 함수로 넘어가는 구조이다.

이상의 코드를 통해서
DB 에서 읽어서 데이터 처리 후, 다시 업데이트 하는 기능을 구현한
실전 구현 코드를 살펴봤다.







댓글 없음:

댓글 쓰기