如何通过firebase的子值按降序分页?

Tyl*_*coe 13 javascript firebase firebase-realtime-database

假设我有一些数据如下:

{
    "name": "post #1",
    "votes": 100
},
{
    "name": "post #2",
    "votes": 10000
},
{
    "name": "post #3",
    "votes": 750
}
Run Code Online (Sandbox Code Playgroud)

等等.

firebase中的数据显然不是通过投票排序的,而是按键排序.

我希望能够按照降序的投票数对这些数据进行分页.

我想我必须做的事情如下:

ref.orderByChild('votes')
    .startAt(someValue)
    .limitToFirst(someOtherValue)
    .once('value', function(snapshot) {
        resolve(snapshot);
    });
Run Code Online (Sandbox Code Playgroud)

或许,我需要使用limitToLast,和endAt

分页key很容易,但是这个让我很难过.

更新(2017-10-16): Firebase最近宣布了Firestore - 他们完全托管的NoSQL数据存储区,可以更轻松地执行更复杂的查询.可能仍有一些用例可能会使用他们一直提供的实时数据库.如果你是其中一个人,这个问题仍应适用.

Tyl*_*coe 31

经过一整天的编码后,我发布了这个问题.

今天早上我又接受了一次破解,并且经常遇到这种情况,能够很快找到解决方案.

解:

为了对数据进行分页,我们需要能够从列表中间任意提取已排序的数据.您可以使用firebase API提供的以下功能执行此操作:

startAt

endAt

limitToFirst

limitToLast

更多信息可以在这里找到.

在我的情况下,因为我需要降序的数据,我会使用endAtlimitToLast.

假设我希望每个页面都有五个项目.我会这样编写我的第一个查询:

ref.orderByChild('votes')
    .limitToLast(5)
    .once('value', function(snapshot) {
      console.log('Snap: ', snapshot.val());
    });
Run Code Online (Sandbox Code Playgroud)

这将获得具有最高投票数的5个项目.

为了获得下一页,我们需要存储上一次查询结果中的两个数据.我们需要存储投票数,以及投票数最少的项目的关键字.也就是说,我们列表中的最后一项.

使用该数据,我们的下一个查询和所有后续查询将如下所示:

ref.orderByChild('votes')
    .endAt(previousVoteCount, previousKey)
    .limitToLast(5)
    .once('value', function(snapshot) {
      console.log('Snap: ', snapshot.val());
    });
Run Code Online (Sandbox Code Playgroud)

你会注意到我在这个查询中添加了endAt.这将获得从前一个列表中的最后一个开始的最多5个项目.我们必须包含上一个列表中最后一个项目的密钥,这样如果有多个项目具有相同的投票数,它将返回一个以正确项目开头的列表,而不是它找到的第一个带有该数字的项目投票,可能在您从初始查询获得的列表中间的某个位置.

而已!

  • AH - 是的......确实关键:-)我一直以为`endAt()`只接受一个参数,值.有道理,我会更新我的其他帖子! (2认同)