[英]Add a mongo request into a file and archive this file
嘗試在MongoDB請求中使用流時遇到一些麻煩。 我想要 :
我正在使用壓縮程序包進行文件壓縮。 該文件包含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.