2013-03-26 2 views
2

Node.js 응용 프로그램의 mapReduce 함수에서 Date 함수를 사용하고 있습니다. 아래지도 함수에서 ISO 날짜 문자열을 Date 객체로 먼저 변환합니다. 그런 다음 날짜의 연도를 가져와 키로 사용합니다. 예상 결과는 출력 콜렉션의 _id가 "2013"입니다. 그러나 사실 _id는 NaN입니다 (유형은 Double 임).Node.js의 MongoDB mapReduce 함수에서 ISO 날짜 스팅을 처리하는 방법

mapReduce 함수 내에서 사용되는 Date 함수가 일반적인 JS Date 함수와 다른 것으로 보입니다.

  1. 지도 기능 내에서 일반 JS 날짜 기능을 어떻게 사용할 수 있습니까?
  2. 불가능할 경우 ISO 기능을 어떻게 처리합니까?

.

var mongodb = require('mongodb'); 

var map = function() { 
    var date = new Date("2013-03-19T08:27:58.001Z"); // Convert ISO date string to Date object 
    var year = date.getFullYear(); // Get the year of the date. 

    emit(year, this); 
}; 


var reduce = function(key, values) { 
    if (values.length) { 
     return values[0]; 
    } 
}; 

/**Connect to MongoDB 
*/ 
var server = new mongodb.Server(dbIP, dbPort, {}); 
var db = new mongodb.Db(dbName, server, {safe:true}); 
db.open(function (err, client) { 
    if(err) { 
     console.log('DB: Failed to connect the database');   
    } 
    else {  
     console.log('DB: Database is connected'); 

     db.collection(collectionName).mapReduce(
      map, 
      reduce, 
      { 
       out: 'map_reduce_collection' 
      } 
      , function (err, collection, stats){    
       if(err) { 
        console.log('Map reduce: Fail.');   
       } 
       else {  
        console.log('Map reduce: Success.'); 
       } 
       db.close(); 
     });  
    } 
}); 

======= 편집 :

ISODate 내 문제를 해결하는 솔루션 =========를 추가합니다. 아래 코드는 나를 위해 작동합니다.

// The map and reduce functions are serialized by the driver and run in the MongoDB server. 
// The functions used in them should be supported by the mongo shell. 
// A tip is checking if a function is supported by map-reduce function by execuing it in the mongo shell. 
// For example, the Date function is different from the one supported by Node.js. 
// In Node.js, the var date = new Date("2013-03-19T08:27:58.001Z"); works. But it doesn't work in mongo shell. 
// So it can't be used in the map function. 
var map = function() { 
    var date = new ISODate("2013-03-19T08:27:58.001Z"); 
    var year = date.getFullYear(); 
    emit(year, this); 
}; 

감사합니다, 제프리 여기

+0

왜 새로운 'Date()'를 'new ISODate()'로 바꾸지 않는가? ISODate는 기본적으로 더 진보 된 더 나은 래퍼이므로 모든 동일한 기능을 사용할 수있다. – Sammaye

+0

FWIW,'map'과'reduce' 함수는 드라이버에 의해 직렬화되어 MongoDB 서버에서 실행됩니다. 따라서 비대칭 성이 발생합니다. – robertklep

+0

감사합니다. Sammaye. 'var date = 새 ISODate ('2013-03-19T08 : 27 : 58.001Z ');' 예상되는 date 객체를 반환합니다. – Jeffrey

답변

1

게시 대답을.

ISODate가 내 문제를 해결합니다. 아래 코드는 나를 위해 작동합니다.

// The map and reduce functions are serialized by the driver and run in the MongoDB server. 
// The functions used in them should be supported by the mongo shell. 
// A tip is checking if a function is supported by map-reduce function by execuing it in the mongo shell. 
// For example, the Date function is different from the one supported by Node.js. 
// In Node.js, the var date = new Date("2013-03-19T08:27:58.001Z"); works. But it doesn't work in mongo shell. 
// So it can't be used in the map function. 
var map = function() { 
    var date = new ISODate("2013-03-19T08:27:58.001Z"); 
    var year = date.getFullYear(); 
    emit(year, this); 
};