首页 > 解决方案 > 如何在firestore中的数百万数据中进行分页?

问题描述

背景

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

我目前将所有块存储在同一个集合中,blocks因为我想对所有分片中的所有块进行完全排序。我曾经将每个分片的块存储在其相应的shardBlocks集合中,但我没有弄清楚如何跨集合进行排序。

我在字段shardIDheight.

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

问题

我正在使用以下代码对从 firestore示例中学到的块进行分页

        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:(

标签: firebasegoogle-cloud-firestore

解决方案


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

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

例如:

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

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

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


推荐阅读