当前位置: 首页 > 知识库问答 >
问题:

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

桑睿识
2023-03-14

假设我正在为评论系统使用Firebase,我想检索给定主题的评论,但是一个主题中有太多评论,我不想一次检索所有评论。我还希望最新的评论显示在顶部。

似乎以相反顺序显示firebase记录的唯一方法是检索所有记录,然后反向迭代它们。

这在大型数据集上可能会变得非常笨拙,尤其是对于移动客户端。

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

共有2个答案

章承
2023-03-14

以下是firebase docs的解决方案:

查询查询=城市。orderBy(“名称”,方向。降序)。限值(3);

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

徐淳
2023-03-14

更新的答案

@Tyler应答stackoverflow。com/a/38024909/681290是这个问题的最新和更方便的答案

TL;博士

如果您希望做的是:

ref.orderBy(field, 'DESC').offset(n).limit(x)

此外,在Firebase github中,有一些不受支持的工具可以进行分页,尽管只按升序排列。

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

使用优先级

我们的目标是在子级上使用setSusPrity()setPrity(),以便以后能够使用orderByPritia()获取有序数据。

问题:

  • 我不认为使用索引的优先级字段有什么好处?(实际上,优先级存储为一个名为priority的底层字段,您可以在导出html" target="_blank">json数据时看到该字段)

具有负数据的冗余子字段

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

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

问题:

  • 它增加了应用程序的复杂性:需要维护额外的字段
  • 可以打破字段的原子性(例如分数字段可以一次更新,不确定是否可以使用两个字段,一个正负)
  • 我认为这个解决方法是在Firebase API中只有限制()时使用的,但现在我们可以使用限制ToFist()限制ToLast()和范围查询(见下文)

使用Limited ToLast()和endAt()范围查询

这让我们避免了负字段和冗余字段:

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

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

在使用之前,只需要反转生成的项目数组。(请记住Array.prototype.reverse()是可变的,因此它会更改您的数组)

问题:

  • API文档指出,只有排序键值才能设置为起始边界或结束边界。如果许多项共享相同的值,则无法在固定长度偏移中拆分数据集

以下项目具有得分值的示例:

{
  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项,而不是API文档中所期望的a、b、c项,因为endAt(1)包含在内,所以它将尝试获得所有分数1,并且无法对之前已返回的项目进行排序。

解决方法

这可以通过不期望每个子集保存相同数量的记录,并丢弃已加载的记录来缓解。

但是,如果我的应用程序的前100万用户的得分为0,则无法对该子集进行分页,因为endAt偏移量是无用的,因为它基于值而不是记录数。

我看不到此用例中有任何解决方法,我想Firebase不适用于此:-)

编辑:最后,我将Algolia用于所有与搜索相关的目的。这是一个非常好的API,我希望谷歌最终收购Algolia以集成两个Firebase

 类似资料:
  • 我有一个通用的链表,目前由int组成,我想在默认情况下按升序排序,然后切换一个布尔值,按降序排序。我该怎么做?

  • 假设我有一些数据如下: 等等 firebase中的数据显然不是按投票排序的,而是按键排序的。 我希望能够按投票数降序排列这些数据。 我想我必须这样做: 或者,我需要使用limitToLast和endAt? 通过分页很容易,但这个难倒了我。 更新(2017年10月16日):Firebase最近宣布Firestore-其完全管理的NoSQL数据存储,这将使执行更复杂的查询更容易。可能仍有一些用例可以使

  • 问题内容: 我将Firebase与Alamofire,AlamofireImage结合使用,以将我的imageURL数据缓存在内存中并上传ImageShack。 我一直尝试创建降序查询并尝试搜索,但是找不到适合我的描述。这是我在Firebase上的测试 ref_post 。 childByAutoId() -userUid -imageUrl -时间戳(我已经使用此时间戳创建了) 使用 NSDat

  • 我们必须按降序对数组进行部分排序。 我知道d::partial_sort但它是按升序排列的。 http://en.cppreference.com/w/cpp/algorithm/partial_sort. 是他们的任何其他这样的功能,可以这样做,或任何快速算法这样做。

  • 我尝试了,但它是按升序排序的。也按升序排序。我查看了stackoverflow,发现的答案都是过时的或引用了RDDS。我想在Spark中使用原生的dataframe。

  • 有人能提供帮助,如何检查排序降序数组以及?干杯!