Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 将mongo请求添加到文件中并存档此文件_Node.js_Mongodb_Express - Fatal编程技术网

Node.js 将mongo请求添加到文件中并存档此文件

Node.js 将mongo请求添加到文件中并存档此文件,node.js,mongodb,express,Node.js,Mongodb,Express,我在尝试使用MongoDB请求流时遇到一些问题。我想: 从集合中获取结果 将此结果放入文件中 将此文件放入CSV 我正在使用用于文件压缩的。该文件包含csv格式的值,因此对于每一行,我必须以csv格式解析它们 我的函数采用res(output)参数,这意味着我可以直接将结果发送到客户端。目前,我可以将这些结果放入一个没有流的文件中。我想我会遇到大量数据的内存问题,这就是为什么我想使用流 这是我的代码(没有流) 函数getCSV(res,query){ .toArray(函数(错误、文档){ va

我在尝试使用MongoDB请求流时遇到一些问题。我想:

  • 从集合中获取结果
  • 将此结果放入文件中
  • 将此文件放入CSV
  • 我正在使用用于文件压缩的。该文件包含csv格式的值,因此对于每一行,我必须以csv格式解析它们

    我的函数采用res(output)参数,这意味着我可以直接将结果发送到客户端。目前,我可以将这些结果放入一个没有流的文件中。我想我会遇到大量数据的内存问题,这就是为什么我想使用流

    这是我的代码(没有流)

    函数getCSV(res,query){ .toArray(函数(错误、文档){ var csv=“”; 如果(文档!==null){ 对于(变量i=0;i 完成csv后,我将其保存到带有Filemanager对象的文件中。后者处理文件创建和操作。addToArchive方法将文件添加到当前存档,sendToClient方法通过输出发送存档(res参数是函数)

    我使用的是Express.js,所以我通过服务器请求调用这个方法

    有时文件包含数据,有时是空的,你能解释一下为什么吗? 我想了解流是如何工作的,如何在代码中实现这一点


    关于

    我不太清楚为什么有时会出现数据显示问题,但这里有一种方法可以通过流发送数据。代码前的几点信息:

    .stream({transform:someFunction})

    从数据库中获取一个文档流,并在每个文档通过该流时对其执行您想要的任何数据操作。我将此函数放入一个闭包中,以便更容易保留列标题,并允许您从文档中选择要用作列的键。这将允许您在不同的集合上使用它

    以下是在每个文档通过时运行的函数:

    // this is a closure containing knowledge of the keys you want to use,
    // as well as whether or not to add the headers before the current line
    function createTransformFunction(keys) {
    
        var hasHeaders = false;
    
        // this is the function that is run on each document 
        // as it passes through the stream
        return function(document) {
    
            var values = [];
            var line;
    
            keys.forEach(function(key) {
    
                // explicitly use 'undefined'. 
                // if using !key, the number 0 would get replaced
                if (document[key] !== "undefined") {
                    values.push(document[key]);
                }
                else {
                    values.push("");
                }
            });
    
            // add the column headers only on the first document
            if (!hasHeaders) {
                line = keys.join(",") + "\r\n";
                line += values.join(",");
                hasHeaders = true;
            }
            else {
                // add the line breaks at the beginning of each line 
                // to avoid having an extra line at the end
                line = "\r\n";
                line += values.join(",");
            }
            // return the document to the stream and move on to the next one
            return line;
        }
    }
    
    将该函数传递到数据库流的转换选项中。现在假设您有一组人,他们的密钥是
    \u id、firstName、lastName

    function (req, res) {
    
        // create a transform function with the keys you want to keep
        var transformPerson = createTransformFunction(["firstName", "lastName"]);
    
        // Create the mongo read stream that uses your transform function
        var readStream = personCollection.find({}).stream({
            transform: transformPerson
        });
    
        // write stream to file
        var localWriteStream = fs.createWriteStream("./localFile.csv");
        readStream.pipe(localWriteStream);
    
        // write stream to download
        res.setHeader("content-type", "text/csv");
        res.setHeader("content-disposition", "attachment; filename=downloadFile.csv");
        readStream.pipe(res);
    }
    

    如果点击此端点,将在浏览器中触发下载并写入本地文件。我没有使用archiver,因为我认为它会增加复杂性,并从实际发生的事情的概念中删除。流都在那里,你只需要稍微摆弄一下就可以与archiver一起使用。

    嗨,谢谢你的解决方案,但文件的问题是我的内存有限。该查询可能会产生多达200万行的数据,并且文件太大,无法存储在磁盘中。这就是为什么我想用archiver来压缩它。然而,我用mongodb做了一个流,但是流永远不会结束。见第5行
    function (req, res) {
    
        // create a transform function with the keys you want to keep
        var transformPerson = createTransformFunction(["firstName", "lastName"]);
    
        // Create the mongo read stream that uses your transform function
        var readStream = personCollection.find({}).stream({
            transform: transformPerson
        });
    
        // write stream to file
        var localWriteStream = fs.createWriteStream("./localFile.csv");
        readStream.pipe(localWriteStream);
    
        // write stream to download
        res.setHeader("content-type", "text/csv");
        res.setHeader("content-disposition", "attachment; filename=downloadFile.csv");
        readStream.pipe(res);
    }