【发布时间】:2020-03-05 19:13:51
【问题描述】:
我需要读取一个非常大的 ASCII 平面文件(150 万行)。它基本上是制造商的零件清单。我想使用 Firestore 来托管它。
作为 .csv 文件,它的大小为 250GB。我能够使用 Windows PowerShell 将其转换为 JSON 文件,现在它的重量超过 1GB。
如何将这些数据导入 Firestore?我认为 Admin SDK 和批量写入将是可行的方法。因此,我完成了所有设置并组装了一个节点脚本,但 Firestore 的 Admin SDK 文档很薄。
我的节点脚本在下面,但它抛出错误FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
var admin = require("firebase-admin");
var serviceAccount = require("./--------------------------.json");
var fs = require('fs');
var myCsvFile = "./global.csv"
var parse = require('csv-parse');
require('should');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://g--------b.firebaseio.com"
});
var firestore = admin.firestore();
var writeBatch = firestore.batch();
var myRef = firestore.collection("foo").doc();
var obj = {};
fs.createReadStream(myCsvFile)
.pipe(parse({delimiter: '|',relax_column_count:true,quote: ''}))
.on('data', function(csvrow) {
if(csvrow[1]){
obj.family = csvrow[1];
}
if(csvrow[2]){
obj.series = csvrow[2];
}
if(csvrow[3]){
obj.sku = csvrow[3];
}
if(csvrow[5]){
obj.description = csvrow[5];
}
if(csvrow[7]){
obj.price = csvrow[7];
}
writeBatch.set(myRef, obj);
})
.on('end',function() {
writeBatch.commit()
});
【问题讨论】:
-
嘿罗恩。关闭 Firestore 本身似乎非常不太可能。如果你能做到,请告诉我,我欠你一个。 :-) 你最有可能在你自己的笔记本电脑上耗尽内存,这(虽然很烦人)也是相当非破坏性的。所以总的来说,试一试,如果你卡住了,请回复你尝试过的和出了什么问题。
-
@FrankvanPuffelen “致命错误:CALL_AND_RETRY_LAST 分配失败 - JavaScript 堆内存不足” ...这是 150 万条记录(sku、描述、系列、系列、价格)。 ...我想知道是否可以在我的机器上创建 JSON 文件,我可以一次上传它 - 而不是尝试批量写入每一行...?
-
嗯...该库看起来应该是流式传输的,但显然您的内存仍然不足。您可能想查看我们的实时数据库流式导入库,该库可以流式传输您提供的 JSON,而不是一次性读取它。
-
哦,等等,我现在看到您只提交了
.on('end'中的批处理。这意味着您正在从整个 CSV 中构建一个批次。当您向其中添加了几百行/文档时,您需要保留一个计数器来记录您添加到批处理中的项目数量并将其提交到.on('data')。 -
这是每个文档。您是否将所有 CSV 数据写入一个文档?因为那样你肯定会很快遇到每个文档 1MB 的限制。
标签: javascript node.js firebase google-cloud-firestore