firebase - 如何在firestore中的数百万数据中进行分页?
问题描述
背景
我们的区块链有数十个分片,每个分片包含数百万个区块。每个块包含shardID
, height
,timestamp
字段
我目前将所有块存储在同一个集合中,blocks
因为我想对所有分片中的所有块进行完全排序。我曾经将每个分片的块存储在其相应的shardBlocks
集合中,但我没有弄清楚如何跨集合进行排序。
我在字段shardID
和height
.
{
"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
批次中的第一个块,我可以使用startAt
或startAfter
获取该批次,而且速度非常快。但我不知道上述timestamp
:(
- 如果我将块拆分为每个分片的集合,我可以
height
用来在每个分片中独立分页。但是,我怎样才能对不同的分片(即集合)进行排序?
解决方案
这可能是运行负载和负载,直到限制高得离谱?您当前正在使用 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 个冗余文档)。
推荐阅读
- python - 如何避免重复进入数据库?
- node.js - 如何在发布事件之前确保聚合存在?
- c# - 在 ASP.NET Core 上实现“一劳永逸”方法的安全方法
- identityserver4 - IdentityServer4:是否可以在运行时更改权限?
- sql - 在 Oracle SQL 中创建全局临时表
- bitwise-and - 按位和负整数不同于按位和正整数
- tomcat - Tomcat - 将数据库连接移出 server.xml
- java - 触发firebase功能后未弹出通知
- xquery - concat(fn:data(value),',') 连接 *all* 字符串,而不仅仅是 value
- android - 参数错误未定义