【问题标题】:How to retrieve random children from Firebase如何从 Firebase 中检索随机子项
【发布时间】:2018-07-26 13:43:05
【问题描述】:

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

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

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

3. Tom 在this firebase discussion 的回答中描述了一种有趣的方法,它建议:

执行此操作的一个 hacky 方法是生成一个随机密钥并使用 startAt().limit(1) 进行查询。我觉得这可能会损害您的火力基地的性能,所以这不应该是您经常执行的操作。我们没有真正的随机样本函数。

这个解决方案实际上听起来不错,但我不确定它会如何影响我的 Firebase。

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

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

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

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

【问题讨论】:

  • 分配 15 个事件监听器是什么意思?你想用 15 个事件监听器做什么?
  • @svi.data 我可能还没有说清楚,我想从父母那里检索一些(比如说 15 个)随机孩子。正如我所说,知道特定孩子的确切 ID(在最后一个方法中描述)意味着分配 15 个听众。例如databaseRef.child("questions").child("id_0001").addSingleValueEventListener(..) 我获得的每个随机 id。
  • 所以你试图获取每个随机 id 下的详细信息(所以你需要使用 15 个事件监听器)?
  • @svi.data 是的。我确实需要获取每个随机 ID 下的详细信息。
  • 那么当然你只使用一个指向你的 (question_ids) 参考的监听器。哪个更好。

标签: android firebase random firebase-realtime-database querying


【解决方案1】:

我们这里有两个案例

案例1

如果您想一次获取随机 id 的所有详细信息,那么我建议父节点使用 1 个侦听器(使用 pojo 类获取数据快照的值)。

案例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....

         });



       });

【讨论】:

  • 在案例 1 中,您的意思是 1 个监听器附加到 questions?在这种情况下,这并不能解决我的问题。这将属于我提出的第一个有两个问题的案例
  • case 1 is 1 listener to (question ids) node .....如果你想要所有的细节,如果不是,那么case 2。
  • 将监听器附加到 question_ids 只能解决一半的问题。我仍然需要获取每个随机 ID 的详细信息。
  • 然后使用 pojo 类。
  • 问题是 POJO。但问题的内容仅在questions 节点中可用。在那里附加一个监听器属于第一类(上面介绍的第一个解决方案)。
【解决方案2】:

您可以使用我在answer 中解释的经典解决方案,但如果您害怕获取大量数据,请使用 15 个侦听器。只要根据活动的生命周期删除它们,使用监听器就没有错。因此,恕我直言,请 15 位听众继续前进。

【讨论】:

  • 所以你提出了我提出的第五个解决方案?在这种情况下,我记得,Firebase 监听器会根据特定的生命周期自动删除,因此无需手动删除(分离)监听器。
  • 是的,第 5 种解决方案。不,他们不是。看看here,看看你需要在哪里移除一个监听器。
  • 我理解并且确实,在这种情况下,我应该删除听众。因此,有没有其他更好的解决方案来解决这个问题?谢谢你,我会接受答案。
  • 您已经提到了可以解决此问题的所有方法。谢谢。干杯!
猜你喜欢
  • 1970-01-01
  • 2018-05-01
  • 1970-01-01
  • 2018-08-25
  • 1970-01-01
  • 1970-01-01
  • 2011-06-29
  • 2021-11-03
相关资源
最近更新 更多