5

tl;dr在 Firebase 中通过 执行基本分页,startAt非常复杂endAtlimit必须有更简单的方法。

我正在为大量用户提交构建一个管理界面。我最初(和当前)的想法是简单地获取所有内容并在客户端上执行分页。然而,在获取 2000 多条记录(每条记录包含 5-6 个小数字/字符串字段)时存在明显的延迟,我将其归因于超过 1.5mb 的数据有效负载。

目前所有条目都是通过添加的,push但我对如何通过巨大的列表进行分页有点迷茫。

要获取我正在使用的第一页数据endAt,其中 alimit为 5:

ref.endAt().limit(10).on('child_added', function(snapshot) {
    console.log(snapshot.name(), snapshot.val().name)
})

结果如下:

-IlNo79stfiYZ61fFkx3 #46 John
-IlNo7AmMk0iXp98oKh5 #47 Robert
-IlNo7BeDXbEe7rB6IQ3 #48 Andrew
-IlNo7CX-WzM0caCS0Xp #49 Frank
-IlNo7DNA0SzEe8Sua16 #50 Jimmmy

首先要弄清楚有多少页,我会保留一个单独的计数器,每当有人添加或删除记录时该计数器就会更新。

其次,由于我正在使用push我无法导航到特定页面,因为我不知道特定页面的最后一条记录的名称,这意味着目前无法使用这样的界面:

标准分页控件

为了简单起见,我决定简单地使用下一个/上一个按钮,但这也带来了一个新问题;如果我使用上一个结果集中第一条记录的名称,我可以使用以下命令分页到下一页:

ref.endAt(null, '-IlNo79stfiYZ61fFkx3').limit(5).on('child_added', function(snapshot) {
    console.log(snapshot.name(), snapshot.val().name)
})

该操作的结果如下:

-IlNo76KDsN53rB1xb-K #42 William
-IlNo77CtgQvjuonF2nH #43 Christian
-IlNo7857XWfMipCa8bv #44 Jim
-IlNo78z11Bkj-XJjbg_ #45 Richard
-IlNo79stfiYZ61fFkx3 #46 John

现在我有了下一页,只是它移动了一个位置,这意味着我必须调整我的限制并忽略最后一条记录。

要后退一页,我必须在客户端上保留到目前为止我收到的每条记录的单独列表,并找出要传递给的名称startAt

有没有更简单的方法可以做到这一点,还是我应该回去取所有东西?

4

3 回答 3

7

我们正在努力添加一个“offset()”查询以方便分页。我们还将添加一个特殊端点,以允许您读取某个位置的子节点数量,而无需实际从服务器加载它们。

不过,这两者都需要一点时间。同时,您描述的方法(或在客户端上完成)可能是您最好的选择。

如果您有一个仅追加的数据结构,则在写入数据时也可能会进行分页。例如:将前 50 个放在 /page1 中,将后 50 个放在 /page2 中,等等。

于 2013-01-20T18:15:37.140 回答
4

实现此目的的另一种方法是使用两棵树:

ids 树:{ id1: id1, id2: id2, id3: id3 }

数据树:{ id1: ..., id2: ..., id3: ... }

然后,您可以将整个 id 树(或其中的一大块)加载到客户端,并使用该 id 树进行精美的分页。

于 2013-01-22T21:45:51.617 回答
2

这是每个方向的分页技巧。

// get 1-5
ref.startAt().limit(5)

// get 6-10 from 5
ref.startAt(null, '5th-firebase-id' + 1).limit(5)

// get 11-15 from 10
ref.startAt(null, '10th-firebase-id' + 1).limit(5)

基本上它是startAtExclusive(). 你可以在 id 的末尾做任何事情。

还想通了endAtExclusive()倒退。

// get 6-10 from 11
ref.endAt(null, '11th-firebase-id'.slice(0, -1)).limit(5)... 

// get 1-5 from 6
ref.endAt(null, '6th-firebase-id'.slice(0, -1)).limit(5)... 

会再玩一些,但似乎可以使用推送 ID。如果使用 firebase 查询,则将limit 替换为limitToFirst或。limitToLast

于 2014-10-30T21:33:52.390 回答