node.js - 使用 Firestore 分页
问题描述
我想用 Firestore 对我的查询进行分页,因为我有一个非常大的集合(超过 2 万个文档在增长)。通过分页,我的意思是向我的用户显示一组数字,如果他点击一个,它会将他重定向到我收藏的特定块,并且只有在他点击时才会获取这个块。例如,如果我有 100 个文档并且我想每页显示 10 个,我有一个从 1 到 10 的数字数组。每次用户点击时,它会加载 10 个产品。
startAfter()
由于这个文档在查询游标上的方法,我已经轻松地实现了无限滚动。
但是,尝试遵循相同的分页文档我就是不明白。我也尝试按照本教程进行操作。
到目前为止,这是我的代码:
let filteredProductsCollection = new Promise(function(resolve, reject) {
productsCollection
.orderBy("productName")
.where(
req.query.where.field,
req.query.where.comparison,
req.query.where.value
)
.startAfter(
req.query.lastProduct
)
.limit(req.query.limit)
.get()
.then(collection => resolve(collection))
.catch(err => reject(err));
}
然后我接受承诺并保存最后一个文件
.then(snapshot => {
let snapshots = {
last
};
snapshot.forEach(doc => {
snapshots[doc.id] = {
...doc.data(),
id: doc.id
};
});
res.status(200).send(data)
})
考虑到当前块(保存在 lastProduct 中),这会获取下一个产品块,使我能够进行完美的无限滚动。
我的主要问题是我不知道如何从它跳转到分页功能。两个主要问题:
- 我不知道我的查询中总共有多少个文档,所以我无法向我的用户显示一个数字数组
- 即使我有这个数组,我将如何检索不直接与已加载的前一个块相邻的特定块?例如,如果我的用户当前在第 1 页,如何查询第 8 页?
似乎所有的教程都直接旨在描述如何进行分页,但我无法理解。我对分页的定义是错误的吗?或者当它真的是“获取下一个数据块”功能时,他们是否称此功能分页......?
解决方案
我不知道我的查询中总共有多少个文档,所以我无法向我的用户显示一个数字数组
Firestore API 中没有计数查询。如果您需要知道文档的总数,则需要加载所有文档,或者在执行更新时保留一个计数器。由于分页旨在防止加载所有文档,因此我将查看有关分布式计数器的文档。
即使我有这个数组,我将如何检索不直接与已加载的前一个块相邻的特定块?例如,如果我的用户当前在第 1 页,如何查询第 8 页?
Firestore API 通常不适合基于偏移的分页。它更适用于按需数据加载的无限滚动方法。如果要实现分页,可以考虑使用服务器端 SDK,它支持基于偏移量的查询。但即使这些也可能不是您需要的,因为您需要为偏移“跳过”的所有文档付费。
我知道的唯一解决方法是为您阅读的每一页保留一个键列表(可能还有您排序的其他字段)。或者保留一个包含所有键的单独集合(因为您可以在文档大小的 1MB 限制中容纳相当多的键)。您可能还想看看FirestorePagingAdapter
FirebaseUI 的实现,它已经实现了分页。
推荐阅读
- arrays - Angular:引导模式值第一次没有绑定
- sql - SQL 更新存储在 ntext 列中的 XML 值
- bash - Basename 在 bash 中删除我的“查找”列表的第二个文件
- php - 动态调用类中的方法
- flutter - 尝试从 youtube-search-tutorial 实现 BLoC 时出现颤振错误
- drools - Drools 规则引擎中的迭代类对象列表问题
- python-3.x - 使用 Fuzzywuzzy 关键字匹配过滤数据框
- bash - Cron 和 Bash 脚本:无法执行
- node.js - socket.io 我应该使用哪些房间或命名空间?
- postman - 如何在 Postman 的 BIM360 中修补项目的版本