【问题标题】:Sort data from FireBase by 2 keys按 2 个键对 FireBase 中的数据进行排序
【发布时间】:2019-02-28 02:43:32
【问题描述】:

我构建了游戏应用程序并将记录保存在 FireBase 的实时数据库中。 数据库外观:

{
    "Ka8xxTgyFB8yYKH50j" : {
        "score" : 10,
        "seconds" : 1325
    },
    "K222xTgyFBF33FD50j" : {
        "score" : 10,
        "seconds" : 425
    },
    "Ka32T23R328yYKH50j" : {
        "score" : 5,
        "seconds" : 115
    },
    "F323F32FB8yYKH50j" : {
        "score" : 30,
        "seconds" : 2335
    }
    }
}

我想从 FireBase 中获取按分数排序的数据,然后按秒排序。 这个例子中数据的正确顺序应该是:

得分:5 秒:115

得分:10 秒:425

得分:10 秒:1325

得分:30 秒:2335

如何使用 orderByChild 或其他方式做到这一点? 谢谢

【问题讨论】:

  • Firebase rt db(如您所知)不允许按多个字段排序,因此您可能必须进行客户端排序。如果您的数据集足够小,这应该不是问题,即使是数千行也应该没问题,除非您经常这样做。

标签: android firebase firebase-realtime-database


【解决方案1】:

由于 firebase 不允许多重排序,我建议您创建一个排序列并根据您的排序要求对其进行更新。 在您的情况下,您可以连接秒和分数,然后将其存储为整数。为了给它一致的长度,秒必须用 0 填充,比如说 6 个字符(取决于你的分数和秒的最大可能值)。 假设,最高分是 100,最大秒数是 50000,您的排序顺序将是 score5 chars of seconds 的组合,转换为整数。

例子:

{
    "Ka8xxTgyFB8yYKH50j" : {
        "score" : 10,
        "seconds" : 1325,
        "sort_order": 1001325
    },
    "K222xTgyFBF33FD50j" : {
        "score" : 10,
        "seconds" : 425,
        "sort_order": 1000425
    },
    "Ka32T23R328yYKH50j" : {
        "score" : 5,
        "seconds" : 115
        "sort_order": 5000115
    },
    "F323F32FB8yYKH50j" : {
        "score" : 30,
        "seconds" : 2335,
        "sort_order": 3002335
    }
}

这样,您可以非常快速地按升序和降序对其进行排序。

【讨论】:

  • 这是一个很酷的概念,从来没有想过在 firebase 中连接订单。虽然如果做太多这些技巧,那么 firebase 可能会被拉伸到极限,应该考虑使用不同的数据库技术。
  • @AndresS 这实际上是在类似 firebase 的数据库中存储东西的首选方式,因为它鼓励非规范化。 Tbh,即使在 sql rdbms 中,您也会根据表模式获得最佳性能。按多列排序意味着大量内存 + 大量 cpu。
  • 当然,但在某些时候,您会用可读性/可维护性来换取可能不会占用大量资源的东西。在超级优化模式下,我可以看到它在许多地方都有好处,但问题始终是“这有必要吗?” (在这种情况下,我认为是的,这是因为限制)
  • 当然这取决于应用程序和数据库软件,但firebase是一个功能非常有限的实时数据库,这意味着低延迟至关重要。在这种情况下,再增加一列来获得 10ms 会很好。
【解决方案2】:

你可以这样试试。 在上传时首先对数据进行排序。

databaseReference.**orderByValue("score")**.addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {

                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {

                            }

                        });

之后,在获取数据的同时再次排序

    setmFirebaseAdapter1(new FirebaseRecyclerAdapter<taskdata, wealth.ShowDataViewHolder>(
                taskdata.class, R.layout.budget_rv_layout, wealth.ShowDataViewHolder.class,retrieceds.**orderByChild(seconds)**) {
            public void populateViewHolder(final wealth.ShowDataViewHolder viewHolder, final taskdata model, final int position) {
})

【讨论】:

    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 2012-11-06
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多