Paginating按时间顺序排列Firebase儿童优先顺序

时间:2013-01-20 17:35:58

标签: firebase

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

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

目前所有条目都是通过push添加的,但我对于如何通过庞大的列表分页是有点迷失。

要获取我使用endAtlimit为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我无法导航到特定页面,因为我不知道特定页面的最后一条记录的名称,这意味着目前这样的界面是不可能的:

Standard pagination controls

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

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的名称。

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

3 个答案:

答案 0 :(得分:7)

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

这两个都需要一点点。与此同时,您描述的方法(或在客户端上完成所有操作)可能是您最好的选择。

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

答案 1 :(得分:4)

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

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

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

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

答案 2 :(得分: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)... 

将更多地玩这个,但似乎与push id一起工作。如果使用firebase查询,请将限制替换为limitToFirstlimitToLast