Node.js 将mongo请求添加到文件中并存档此文件
我在尝试使用MongoDB请求流时遇到一些问题。我想:Node.js 将mongo请求添加到文件中并存档此文件,node.js,mongodb,express,Node.js,Mongodb,Express,我在尝试使用MongoDB请求流时遇到一些问题。我想: 从集合中获取结果 将此结果放入文件中 将此文件放入CSV 我正在使用用于文件压缩的。该文件包含csv格式的值,因此对于每一行,我必须以csv格式解析它们 我的函数采用res(output)参数,这意味着我可以直接将结果发送到客户端。目前,我可以将这些结果放入一个没有流的文件中。我想我会遇到大量数据的内存问题,这就是为什么我想使用流 这是我的代码(没有流) 函数getCSV(res,query){ .toArray(函数(错误、文档){ va
关于我不太清楚为什么有时会出现数据显示问题,但这里有一种方法可以通过流发送数据。代码前的几点信息:
.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);
}