Как обработать привязку даты ISO в функции MongoDB mapReduce в Node.js

Я использую функцию Date в функции mapReduce в приложении Node.js. В приведенной ниже функции карты я сначала конвертирую строку даты ISO в объект Date. Затем получите год даты, который будет использоваться в качестве ключа. Ожидаемый результат - _id в выходной коллекции - «2013». Но на самом деле _id - это NaN (тип - Double).

Кажется, что функция Date, используемая внутри функции mapReduce, отличается от обычной функции JS Date.

  1. Как я могу использовать обычную функцию JS Date внутри функции карты ниже?
  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);
};

Спасибо Джеффри


person Jeffrey    schedule 26.03.2013    source источник
comment
Почему бы вам не заменить new Date() на new ISODate(), ISODate в основном является более продвинутой и лучшей оболочкой для даты, поэтому вы можете использовать все те же функции.   -  person Sammaye    schedule 26.03.2013
comment
FWIW, функции map и reduce сериализуются драйвером и запускаются на сервере MongoDB, отсюда и асимметрия.   -  person robertklep    schedule 26.03.2013
comment
Спасибо, Саммай. 'Var date = new ISODate (2013-03-19T08: 27: 58.001Z);' возвращает объект ожидаемой даты.   -  person Jeffrey    schedule 26.03.2013
comment
Если вы решили свою проблему, вам следует либо опубликовать свой ответ ниже, который вы можете принять через 48 часов, либо, если вы считаете, что ваш вопрос / ответ не имеет отношения к будущим посетителям, вы можете полностью удалить свой вопрос. Вам не следует просто редактировать свой вопрос с решением. Или @Sammaye должны сами добавить ответ.   -  person Andrew Marshall    schedule 26.05.2013


Ответы (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);
};
person Jeffrey    schedule 31.05.2013
comment
Отметьте это как правильный ответ. Это тоже решило мою проблему. Спасибо! - person Yussuf; 28.02.2020