如何从 Firebase 中检索随机 children

How to retrieve random children from Firebase

假设我们想从 questions 节点中检索 15 个随机 children,该节点的数据库结构如下:

1. 从 Firebase 中检索随机 children 的第一种(直观且经过讨论的)方法是检索整个所需的 parent 节点(questions 作为数据快照)然后 select 在 client-side 上随机 children。这个方法已经在很多帖子中指出,例如。 显然,这种方法有其缺点;例如,当通过大型 parent 节点(例如超过 10.000 children)进行查询时,每次检索这样的数量将导致 巨大的带宽使用量 以及客户端负担。(当我们实际上只需要少量 children)

2. 继续:另一种方法,如 所述,它使用迭代器以某种方式绕过了整个客户端负担,但是 巨大的当我们每次下载整个 parent 节点时,带宽使用 仍然可能发生。

3. 汤姆在 this firebase discussion 的回答中描述了一种有趣的方法,它提出:

A hacky way of doing this would be to generate a random key and do a query with startAt().limit(1). I have a feeling this could hurt the performance of your firebase though, so this should not be an operation you perform often. We don't have a real random sample function.

这个解决方案实际上听起来不错,但我不确定它会对我的 Firebase 产生怎样的影响。

4. 另一个愚蠢的解决方案实际上可能是手动命名问题 ID,可以这么说,从 0 到 N,因此在客户端处理随机 ID 组,并且通过了解节点的实际名称来检索问题 spot-on。

5.最后,我提出了以下解决方案,我询问它是否比上面介绍的方案更可行或更不可行: 创建另一个 parent 仅包含问题 ID,并且在需要时,应该检索比 questions parent “轻”得多的 parent 。从那里,我会有特定的随机 ID,我只需要狙击那些 children。为了更好地理解我的意思,请查看下图:

现在,此方法会引发以下问题:分配(比方说)15 eventListeners 是好的做法吗?这真的可以减慢速度吗? (注意:这也适用于方法 3 和 4)

最终,当从大型数据库中查询一些随机 children 时,哪种方法实际上是最佳方法?

我们这里有2个案例

案例 1

如果您想一次获取随机 ID 的所有详细信息,那么我建议 1 个侦听器到父节点(使用 pojo class 获取 datasnapshot 的值)。

案例 2

如果您想根据请求独立获取详细信息,则必须为每个所需的(随机 ID)附加一个侦听器。

关于性能

尝试只对单值事件使用监听器,因为它们监听一次然后停止(性能更好)。

不要使用值事件侦听器(因为这些侦听器会不断检查更改,因此随着侦听器的增加性能会变差)。

编辑

假设你听了 (questions_ids) 节点,现在你可以访问随机 id 键,将它们存储在一个 String 变量中,然后在同一个监听器中添加另一个监听器到 (questions) 指向到你要抓取详情的id

      //first listen to question ids ref (the one with 15 ids)

       question_ids_ref.addListenerForSingleValueEvent(...{
       //grab the key of each (random id) and store in variable

        String random_01=......;

        //run another listener this time to questions ref

             questions_ref.child(random_01).addListenerForSingleValueEvent(..{

             //get details of random_01 and so on....

         });



       });

您可以使用我在此 中解释的经典解决方案,但如果您害怕获得大量数据,请改用 15 个侦听器。只要您根据 activity 的 life-cycle 删除它们,使用监听器就没有错。所以,恕我直言,继续听 15 位听众。