如何定期将大型 JSON 数据集导入 Cloud Firestore?

Posted

技术标签:

【中文标题】如何定期将大型 JSON 数据集导入 Cloud Firestore?【英文标题】:How to import large JSON datasets to Cloud Firestore periodically? 【发布时间】:2021-04-18 11:53:11 【问题描述】:

我正在尝试导入包含 18 万条记录的 JSON。正如您在这段代码中看到的,我每次运行可以上传 500 条记录,但我需要定期上传 180k 条记录。

我想要实现的目标:

    解析 JSON(完成)。 从每个 JSON 元素创建模型 (DONE) 将此上传到 Cloud Firestore(已完成,但每个文档 500 个)

模型工厂:

factory Academician.fromJson(Map<String, dynamic> json) => Academician(
        // Using this to parse data from JSON, 
        // rating and reviewList does not exist in JSON, 
        // that's why i need custom model 
        name: json["name"] ?? "",
        designation: json["designation"] ?? "",
        field: json["field"] ?? "",
        universityName: json["university"] ?? "",
        department: json["department"] ?? "",
        rating: 0,
        reviewList: [],
      );

解析并上传到 Cloud Firestore:

parseJsonFromAssets('json/akademik_kadro.json')
        .then((value) => value['Sayfa1'].forEach((value) 
              academicianList.add(Academician.fromJson(value));
            ))
        .then((value) 
            setState(() 
                for (int z = 0; z < 500; z++) 
                    //500 is the single time upload limit to Cloud Firestore 
                    //I guess
                    dbOperation.addToCollection(academicianList[z]);
            
          );
        );

【问题讨论】:

【参考方案1】:

您似乎已达到writes and transactions 500 的限制。

Limit Details
Maximum API request size 10 MiB
Maximum number of writes that can be passed to a Commit operation or performed in a transaction 500
Maximum number of field transformations that can be performed on a single document in a Commit operation or in a transaction 500

更好的方法是使用Batched writes。

批量写入最多可包含 500 个操作。批处理中的每个操作都单独计入您的 Cloud Firestore 使用量。在写入操作中,字段转换为 serverTimestamparrayUnion,并将每个计数递增作为附加操作。

您可以像这样构建目录:

batch_uploader\
    json_files\
        json_1.json   
        json_1.json
        json_1.json 
        json_1.json
    uploader.js
    ....

uploader.js

var admin = require("firebase-admin");

var serviceAccount = require("./service_key.json");

admin.initializeApp(
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "YOUR_PROJECT_LINK"
);

const firestore = admin.firestore();
const path = require("path");
const fs = require("fs");
const directoryPath = path.join(__dirname, "files");

fs.readdir(directoryPath, function(err, files) 
  if (err) 
    return console.log("Unable to scan directory: " + err);
  

  files.forEach(function(file) 
    var lastDotIndex = file.lastIndexOf(".");

    var menu = require("./json_files/" + file);

    menu.forEach(function(obj) 
      firestore
        .collection(file.substring(0, lastDotIndex))
        .doc(obj.itemID)
        .set(obj)
        .then(function(docRef) 
          console.log("Document written");
        )
        .catch(function(error) 
          console.error("Error adding document: ", error);
        );
    );
  );
);

如果你想定期运行脚本,你可以schedule a function在指定的时间运行。例如,要每五分钟运行一次脚本,您可以执行以下操作:

exports.scheduledFunction = functions.pubsub.schedule('every 5 minutes').onRun((context) => 
  console.log('This will be run every 5 minutes!');
  return null;
);

【讨论】:

那么,我必须为此使用云功能吗? 如果你想安排导入,那么可以。

以上是关于如何定期将大型 JSON 数据集导入 Cloud Firestore?的主要内容,如果未能解决你的问题,请参考以下文章

我们如何将大型数据集从 Google BigQuery 导入 R?

如何将公共数据集导入 Google Cloud Bucket

如何将 CSV 或 JSON 导入到 Firebase Cloud Firestore

如何从 pandas 数据框中的大型每日 JSON 数据集计算平均月值?

Pentaho 数据集成 从数据库导入大型数据集

如何在 python 中处理大型图像数据集?