Как загрузить всю коллекцию с более чем 500k записей в виде csv с nodejs из mongodb? - PullRequest
0 голосов
/ 27 февраля 2019

Я пробовал это с пакетом npm, который называется json2csv.Он работает нормально для записей до 75 000. Когда данных больше этого, я не получаю никакого ответа от функции обратного вызова exporttocsv, как указано ниже.

    const json2csv = require('json2csv').parse;
    var today = new Date();
var mongoClient = require('mongodb').MongoClient
, assert = require('assert');
    var dd = today.getDate();
    var mm = today.getMonth() + 1; //January is 0!
    var yyyy = today.getFullYear();
    if (dd < 10) {
      dd = '0' + dd;
    } 
    if (mm < 10) {
      mm = '0' + mm;
    } 
    var today = dd + '_' + mm + '_' + yyyy;



    router.put('/mass_report', (req, res) => {

        mass_data_download();
        res.json("Mass report download initiated");

    });

    function exporttocsv(data,name, callback) {
        /* Start: Json to xlsx conversion */
        if (!fs.existsSync('./csv/'+today+'/')) {
            fs.mkdirSync('./csv/'+today+'/');
        }

        var csv = json2csv(data);

        var fname = './csv/'+today+'/' +name+ new Date().getTime() + '.csv';
        fs.writeFileSync(fname, csv, 'binary',(error,response)=>{
            console.log(error);
            console.log(response);
        });
        callback(fname);

    }

    function mass_data_download(){


        db.collection('mass_data').aggregate([
            {$match:{
                created_on: {
                    $gte: new Date("2017-09-01T00:00:00.000Z"),
                }
            }}

        ]).sort({_id:-1}).toArray( function (error, response) {
        if(error){
            console.log(error)
        }
        else{
            console.log(response.length);
            exporttocsv(response,'mass_report', function (fname) {

                console.log('reports download complted');



            })

        }

            })
    }

есть ли ограничения при экспорте данных вCSV?или как этого добиться с помощью любых других альтернатив?

1 Ответ

0 голосов
/ 27 февраля 2019

Дело в том, что вы обрабатываете огромное количество данных в памяти одновременно.Вы должны избегать этого любой ценой.Node.js идеально подходит для использования потоков, совмещенных с ним.Считайте Mongo вашим читаемым потоком, затем направьте его в поток преобразования json2csv и сделайте то, что вы хотите, с результатом, возможно, вы захотите передать его в поток для записи, такой как файл или даже HTTP-ответ.

Mongoose поддерживает потоковую передачу.Более подробную информацию вы можете найти здесь json2csv также поддерживает потоковый интерфейс. здесь - больше информации о потоковом API json2csv.

ОБНОВЛЕНО : конечный псевдокод должен выглядеть следующим образом:

const csv = fs.createWriteStream('file.csv');

Model.find()
    .cursor()  // read more [here][1] 
    .pipe(json2csvTransformStream) // read more in json2csv transform stream API
    .pipe(csv); // read more in fs.createWritableStream

Трубопровод будет обрабатывать весь потокпоток, и вы не будете беспокоиться об утечках памяти или производительности.

...