簡體   English   中英

將mongo請求添加到文件中並將其存檔

[英]Add a mongo request into a file and archive this file

嘗試在MongoDB請求中使用流時遇到一些麻煩。 我想要 :

  1. 從集合中獲取結果
  2. 將此結果放入文件中
  3. 將此文件放入CSV

我正在使用壓縮程序包進行文件壓縮。 該文件包含csv格式的值,因此對於每一行,我都必須以CSV格式解析它們。

我的函數采用res(輸出)參數,這意味着我可以將結果直接發送到客戶端。 目前,我可以將結果放入沒有流的文件中。 我想我會為大量數據遇到內存問題,這就是為什么我要使用流。

這是我的代碼(沒有流)

function getCSV(res,query) {

  <dbRequest>.toArray(function(err,docs){
    var csv = '';
    if(docs !== null){
        for(var i = 0; i< docs.length; i++){
            var line = '';

            for(var index in docs[i]){
                if(docs[i].hasOwnProperty(index) && (index !== '_id' ) ){

                    if(line !== '') line+= ',';

                    line += docs[i][index];
                }
            }

                console.log("line",line);

            csv += line += '\r\n';
        }

    }
}.bind(this));

    fileManager.addToFile(csv);

    archiver.initialize();
    archiver.addToArchive(fileManager.getName());
    fileManager.deleteFile();

    archiver.sendToClient(res);
};

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;
    }
}

您將該函數傳遞到數據庫流的transform選項中。 現在假設您有一個具有_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一起使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM