批量写入firebase云firestore

时间:2018-02-23 04:49:35

标签: node.js firebase google-cloud-firestore

我想创建一个新的集合,并添加数千个大小~1KK的文档。我已经在json中有数据,所以我觉得这很容易。

我知道批处理一次可以有500个写入,所以要把它分成500个块我写了下面的代码。虽然出于测试目的,我运行它的块数为20,而我的测试json有72个对象。

但我一直收到以下错误

node_modules\@google-cloud\firestore\src\write-batch.js:148
  throw new Error('Cannot modify a WriteBatch that has been committed.');
  ^

Error: Cannot modify a WriteBatch that has been committed.

我的代码如下

var dataObj = JSON.parse(fs.readFileSync('./bigt.json'))
var tmpdd = dataObj.slice(0, 72)
var batch = db.batch();

console.log(tmpdd.length)

let tc = tmpdd.length
let lc = 0
let upperLimit = 20, dd = null

while(lc<=tc){

    dd = tmpdd.slice(lc, upperLimit )

    console.log(lc, upperLimit)
    dd.map(
    o => batch.set(db.collection('nseStocks').doc(o.Date+o.variable), o)
    )

    batch.commit().then(function () {
        console.log('Written to firestore', lc, lc + upperLimit)
    })
    .catch(
        (err) => console.log('Fail', err)
    )

    lc = upperLimit
    upperLimit = upperLimit + 20 

}

同样奇怪的是,批次似乎没有在循环的每次迭代中提交。理想情况下,我会让Firestore确定文档ID,但显然批处理没有添加功能。

我尝试在循环中添加文档而不是批量写入。但是在添加一些文档后它会给我超时错误。当然,对于大量文档来说,它并不实用。

你可以说我对Firestore来说很新,而且这是我第二天玩它。

如果有任何明显的错误或更好的方法来实现这项看似简单的任务,请告诉我。

由于

2 个答案:

答案 0 :(得分:3)

这对我有用:

function loadJson(){
    var ref = firebase.firestore().collection("my-parent-collection-name");
    getJSON("https://my-target-domain.com/my-500-plus-objects-file.json").then(function (data) {
        var counter = 0;
        var commitCounter = 0;
        var batches = [];
        batches[commitCounter] = db.batch();
        Object.keys(data).forEach(function(k, i) {
            if(counter <= 498){
                var thisRef = ref.doc(k);
                batches[commitCounter].set(thisRef, data[k]);
                counter = counter + 1;
            } else {
                counter = 0;
                commitCounter = commitCounter + 1;
                batches[commitCounter] = db.batch();
            }
        });
        for (var i = 0; i < batches.length; i++) {
            batches[i].commit().then(function () {
                console.count('wrote batch');
            });
        }
    }, function (status) {
        console.log('failed');
    });

}
loadJson();

答案 1 :(得分:2)

您正在为程序的顶级所有写入创建一个批处理。它会被重用于您为所有批量写入进行的batch.set()的所有调用。

var batch = db.batch();

相反,您应该为每组写入创建一个新批处理。您可以在while循环的顶部执行此操作:

while(lc<=tc) {
    var batch = db.batch();
    // use the new batch here
}