Пакетная запись в Firestore с Admin SDK - PullRequest
0 голосов
/ 24 июня 2018

У меня есть очень большой плоский файл ASCII (1,5 миллиона строк), который мне нужно прочитать.Это в основном список деталей от производителя.Я хотел бы использовать Firestore для его размещения.

Как файл .csv, он весит 250 ГБ.Мне удалось преобразовать его в файл JSON с помощью Windows PowerShell, и теперь он весит более 1 ГБ.

Как получить эти данные в Firestore?Я думаю, что Admin SDK и пакетная запись будет путь.Итак, я получил все настройки и собрал скрипт узла, но документация Admin SDK для Firestore тонкая.

Мой скрипт узла ниже, но выдает ошибку 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()
    });

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

500 записей могут быть записаны в секунду.Таким образом, ключом является ограничение скорости .commit до 1 в секунду и ограничение batch.set до 500 за фиксацию.Я получил это, работая с aynch / await в качестве ограничителя скорости, а также с шаблоном стиля promise.all, который толкает .set в увеличивающийся массив .batch es.

Oh, и последнее, что япришлось сказать Node использовать больше памяти с переключателем --max-old-space-size.

Сценарий ниже был скопирован с 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.");
}
0 голосов
/ 24 июня 2018

Пакетная запись в указанных пределах не вызовет никаких проблем в вашем случае. Я не думаю, что у вас есть какие-либо альтернативы в настоящее время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...