【问题标题】:Paginate with Firestore使用 Firestore 分页
【发布时间】:2019-04-21 20:40:07
【问题描述】:

我想使用 Firestore 对我的查询进行分页,因为我有一个非常大的集合(超过 2 万个文档正在增长)。通过分页,我的意思是向我的用户显示一组数字,如果他点击一个,它会将他重定向到我收藏的特定块,并且只有在他点击时才会获取这个块。例如,如果我有 100 个文档,并且我想每页显示 10 个,我有一个从 1 到 10 的数字数组。用户每次点击时,它会加载 10 个产品。

感谢startAfter() 方法和查询游标上的doc,我轻松实现了无限滚动。

但是,尝试遵循相同的分页文档我就是不明白。我也尝试关注这个tutorial

这是我目前的代码:

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 页?

似乎所有的教程都直接旨在描述如何进行分页,但我无法理解。我对分页的定义是错误的吗?或者当它实际上是一个“获取下一个数据块”功能时,他们是否称此功能分页......?

【问题讨论】:

    标签: node.js google-cloud-firestore


    【解决方案1】:

    我不知道我的查询中总共有多少个文档,所以我无法向我的用户显示一个数字数组

    Firestore API 中没有计数查询。如果您需要知道文档的总数,则需要加载所有文档,或者在执行更新时保留一个计数器。由于分页是为了防止加载所有文档,所以我会查看distributed counters 上的文档。

    即使我有这个数组,我将如何检索不直接与已加载的前一个块相邻的特定块?例如,如果我的用户当前在第 1 页,如何查询第 8 页?

    Firestore API 通常不适合基于偏移的分页。它更适用于按需数据加载的无限滚动方法。如果你想实现分页,你可以考虑使用支持offset-based queries的服务器端SDK。但即使这些也可能不是您所需要的,因为您需要为偏移“跳过”的所有文档付费。

    我知道的唯一解决方法是为您阅读的每个页面保留一个键列表(可能还有您排序的其他字段)。或者保留一个包含所有键的单独集合(因为您可以在文档大小的 1MB 限制中容纳相当多的键)。您可能还想看看FirestorePagingAdapter implementation of FirebaseUI,它已经实现了分页。

    【讨论】:

    • 但是建立索引的目的不就是我不必自己跟踪计数吗?这个计数可能会变得非常复杂,因为查询每次都会更改(它们是页面上的过滤器,因此您每次都查询同一个集合,但不是所有文档)
    • 计数查询不是 Firestore API 的一部分。如果您需要计数,您需要自己跟踪它。如果您觉得这很复杂,您可能会想像为什么 Firestore 不支持它们,因为它必须在它支持的任何查询功能上保持其性能保证。
    • 如果您正在考虑对实时观察者进行分页,我强烈建议您考虑该用例对您的应用程序的重要性。实现起来并不简单,而且会占用大量时间,您还可以花在其他功能上。
    • 感谢您的回复。是的,我不会选择计数解决方案,因为它太复杂了。考虑过抵消,但成本太高。我会阅读您提出的解决方案。我还将尝试一个我考虑过的解决方法(显示这样的页面“1 2 3 4 5 >>”并实际获取所有这些页面的结果,如果用户单击箭头,则获取接下来 5 个页面的数据等等在)。基本上我们正在将无限滚动转换为分页功能,这就是原因。但是,无限滚动很容易用firestore实现。完成后我会完成我的答案。
    猜你喜欢
    • 2020-03-30
    • 1970-01-01
    • 2018-10-26
    • 2021-03-31
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 2019-05-29
    相关资源
    最近更新 更多