我有一个非常大的 ASCII 平面文件(150 万行),我需要读取它。它基本上是制造商提供的零件列表。我想使用 Firestore 来托管它。
作为 .csv 文件,其大小为 250GB。我能够使用 Windows PowerShell 将其转换为 JSON 文件,现在它的大小超过 1GB。
如何将该数据导入 Firestore?我认为管理 SDK 和批量写入将是可行的方法。因此,我完成了所有设置并组装了 Node 脚本,但 Firestore 的管理 SDK 文档很薄弱。
我的 Node 脚本如下,但它抛出错误 fatal error :CALL_AND_RETRY_LAST分配失败 - JavaScript堆内存不足
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()
});
最佳答案
每秒可写入 500 个条目。因此,关键是将 .commit
速率限制为每秒 1 次,并将 batch.set
限制为每次提交 500 次以下。我使用 aynch/await 作为速率限制器,以及将 .set
插入 .batch 递增数组的
es。promise.all
样式模式。
哦,最后一件事 - 我必须通过 --max-old-space-size
开关告诉 Node 使用更多内存。
下面的脚本复制自 High Tech Telecom :
var admin = require("firebase-admin"); var serviceAccount = require("./your-firebase-project-service-account-key.json"); var fs = require('fs'); var csvFile = "./my-huge-file.csv" var parse = require('csv-parse'); require('should'); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://your-project.firebaseio.com" }); var firestore = admin.firestore(); var thisRef; var obj = {}; var counter = 0; var commitCounter = 0; var batches = []; batches[commitCounter] = firestore.batch(); fs.createReadStream(csvFile) .pipe( parse({delimiter: '|',relax_column_count:true,quote: ''}) ) .on('data', function(csvrow) { if(counter <= 498){ if(csvrow[1]){ obj.family = csvrow[1]; } if(csvrow[2]){ obj.series = csvrow[2]; } if(csvrow[3]){ obj.sku = csvrow[3]; } if(csvrow[4]){ obj.description = csvrow[4]; } if(csvrow[6]){ obj.price = csvrow[6]; } thisRef = firestore.collection("your-collection-name").doc(); batches[commitCounter].set(thisRef, obj); counter = counter + 1; } else { counter = 0; commitCounter = commitCounter + 1; batches[commitCounter] = firestore.batch(); } }) .on('end',function() { writeToDb(batches); }); function oneSecond() { return new Promise(resolve => { setTimeout(() => { resolve('resolved'); }, 1010); }); } async function writeToDb(arr) { console.log("beginning write"); for (var i = 0; i < arr.length; i++) { await oneSecond(); arr[i].commit().then(function () { console.log("wrote batch " + i); }); } console.log("done."); }
关于javascript - 使用 Admin SDK 批量写入 Firestore,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51012014/