如何使用mongodb中的nodejs下载超过500k记录的整个集合作为csv?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用mongodb中的nodejs下载超过500k记录的整个集合作为csv?相关的知识,希望对你有一定的参考价值。

我已经尝试使用名为json2csv的npm包。它对于高达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时是否有任何限制?或者如何用其他替代品来实现这一目标?

答案

问题是你在同时处理大量内存中的数据。你应该不惜一切代价避免它。 Node.js非常适合使用流,背上它。将Mongo视为您的可读流然后将其传输到json2csv转换流并使用结果执行您想要的操作,或许您希望将其传输到可写流(例如文件甚至http响应)。

Mongoose支持流媒体。您可以找到更多信息here json2csv也支持流媒体界面。 here是关于json2csv的流API的更多信息。

更新:最终伪代码应如下所示:

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

管道将处理所有流的流量,您不会担心内存泄漏或性能。

以上是关于如何使用mongodb中的nodejs下载超过500k记录的整个集合作为csv?的主要内容,如果未能解决你的问题,请参考以下文章

Mongodb插入50M文档而不重复的最佳方法

如何使用nodeJS更新mongodb中的值?

nodejs中如何同步连接mongodb

如何使用 NodeJS 将数据添加到 MongoDB 中的数组属性?

使用日期从 mongodb-nodejs 驱动程序获取文档

我们如何使用带有 expressjs-nodejs 的 mongoose 对 mongodb 中的 ObjectId 列执行排序?