如何在Firebase中按升序或降序检索分页子项?

时间:2014-11-28 21:02:25

标签: javascript pagination firebase

假设我正在使用firebase作为评论系统,我想检索给定主题的评论,但是在一个主题中有很多评论我不想一次全部检索它们。我还希望最新的评论显示在最上面。

似乎以相反的顺序显示firebase记录的唯一方法是将它们全部检索,然后反过来迭代它们。

对于大型数据集,这可能非常笨拙,特别是对于移动客户端。

还有更好的方法吗?从Firebase查询分页数据的通用和首选解决方案是升序还是降序?

2 个答案:

答案 0 :(得分:11)

更新回答

@Tyler answer stackoverflow.com/a/38024909/681290是这个问题的最新且更方便的答案

<强> TL; DR

如果您要做的是:

,则无法解决
ref.orderBy(field, 'DESC').offset(n).limit(x)

此外,在Firebase github中,有不受支持的工具that do pagination,但仅限升序

否则,以下是我自己找到的最接近的解决方案,或者到目前为止在网上找到的解决方案。我故意将这个问题解释为通用的,而不仅仅是关于OP所要求的时间字段。

使用优先级

目标是让儿童使用setWithPriority()setPriority(),以便稍后使用orderByPriority()获取有序数据。

问题:

  • 我没有看到使用索引priority字段的优势? (实际上,优先级存储为名为.priority的基础字段,导出json数据时可以看到)
  • 难以维护许多用例,以确定要设置的优先级值

包含负数据的冗余子字段

例如,除了timeRev之外,我们还可以使用负时间戳time索引字段来首先获取最新项目。

ref.orderByChild('timeRev')
   .limitToFirst(100);

问题:

  • 它增加了应用程序的复杂性:需要维护其他字段
  • 可以打破字段的原子性(例如,score字段可以立即更新,不确定它是否可以使用两个字段,一个是正字段,一个是负字段“
  • 我认为当Firebase API中只有limit()时会使用此解决方法,但由于我们可以使用limitToFist()limitToLast()和范围查询(请参阅下文),因此有点过时了)

使用limitToLast()和endAt()范围查询

这让我们避免消极和冗余的领域:

ref.orderBy('time')
   .limitToLast(100)

这对于时间戳字段应该非常有效,因为通常这是一个唯一的字段。

在使用之前,只需要反转生成的项目数组。 (只记得Array.prototype.reverse()是可变的,所以它会改变你的数组)

问题:

  • API文档说只有有序键值可以设置为startAtendAt边界。如果许多项共享相同的值,则无法将数据集拆分为固定长度的偏移量。

以下项目持有score值的示例:

{
  items: {
    a: {score: 0},
    b: {score: 0},
    c: {score: 1},
    d: {score: 1},
    e: {score: 2},
    f: {score: 5}
  }
}

首页查询以获得最佳得分项目:

ref.child('items').orderByChild('score')
   .limitToLast(3)

结果:

{
  d: {score: 1},
  e: {score: 2},
  f: {score: 5}
}

请注意,该子集的第一项具有1分数,因此我们尝试通过选择分数为1或更低的所有项目来获取上一页:

ref.child('items').orderByChild('score')
   .endAt(1)
   .limitToLast(3)

根据该查询,我们会获得b,c,d个项目,而不是a,b,c个项目,这些项目是根据API文档预期的,因为endAt(1)具有包容性,因此它会尝试获取所有分数为1,并且无法对之前已经返回的内容进行排序。

解决方法

可以通过不期望每个子集保持相同数量的记录并丢弃已经加载的记录来减轻这种情况。

但是,如果我的应用的第一百万用户的分数为0,则此子集无法进行分页,因为endAt偏移无用,因为它基于在而不是记录数

我没有看到此用例的任何解决方法,我认为Firebase不适用于此: - )

编辑:最后,我使用Algolia用于所有与搜索相关的目的。它是一个非常好的API,我希望谷歌最终收购Algolia以整合Firebase和amp; Algolia,因为它们的互补性接近100%!免责声明:没有股份! : - )

答案 1 :(得分:0)

这是firebase文档的解决方案:

查询查询= city.orderBy(“ name”,Direction.DESCENDING).limit(3);

https://firebase.google.com/docs/firestore/query-data/order-limit-data