如何在Firestore中的数百万个数据之间分页?

时间:2019-09-18 07:20:55

标签: firebase google-cloud-firestore

背景

我们的区块链有数十个分片,每个分片包含数百万个块。每个块包含shardIDheighttimestamp个字段

我目前将所有块存储在称为blocks的同一集合中,因为我想对所有分片上的所有块进行排序。我曾经将每个分片的块存储在其对应的shardBlocks集合中,但是我不知道如何对集合进行排序。

我在字段shardIDheight上创建了复合索引。

{
  "collectionGroup": "blocks",
  "queryScope": "COLLECTION",
  "fields": [
    { "fieldPath": "shardID", "order": "ASCENDING" },
    { "fieldPath": "height", "order": "DESCENDING" }
  ]
}

问题

我正在使用以下代码对从Firestore example学到的块进行分页

        let query = await this.blocksCollection.orderBy("timestamp", "desc");

        let start = pageIndex * pageSize;
        if (start) {
            let a = Date.now();
            let skip = await this.blocksCol
                .orderBy("timestamp", "desc")
                .limit(start)
                .get();
            let prev = skip.docs[skip.docs.length - 1];
            query = query.startAfter(prev);
        }

        let snapshot = await query.limit(pageSize).get();
        return snapshot.docs.map(d => d.data()) as Block[];

但是它很容易出现错误Bandwidth exhausted。以前我还记得我曾经看到过错误消息,说最大限制是10000。

问题

  • 在这种情况下如何分页?

我尝试过,如果我知道批处理中第一个块的timestamp,则可以使用startAtstartAfter来获取该批处理,而且速度非常快。但是我不知道前面提到的timestamp:(

  • 如果我将每个分片将块分割成多个集合,则可以使用height独立地对每个分片进行分页。但是我该如何对不同的碎片(即集合)进行排序?

1 个答案:

答案 0 :(得分:1)

这是运行的负载和时间的负载,直到极限高得离谱吗?您当前正在使用limit(start),这似乎是触发太多读取的罪魁祸首。我会使用一个静态数字作为您的限额,然后从那里开始。

如果pageSize保持不变,而pageIndex不断增加,则可能会多次抓取前几个文档,或者在每页之后,您正在增加调用的大小。

例如:

第一页,pageIndex = 0,pageSize = 25,开始=0。这不会加载任何内容。

第二页,pageIndex = 1,pageSize = 25,开始=25。这将加载25个文档。

第3页,pageIndex = 2,pageSize = 25,开始=50。这将加载50个文档,包括您已经从第二页加载的文档(这意味着您现在有25个冗余文档)。