Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firebase数据库按更深的子级排序_Firebase_Firebase Realtime Database - Fatal编程技术网

Firebase数据库按更深的子级排序

Firebase数据库按更深的子级排序,firebase,firebase-realtime-database,Firebase,Firebase Realtime Database,考虑到Firebase数据库的以下结构: 根 游戏1 $playerUidA 分数:50 $playerUidB 分数:10 游戏2 $playerUidC 分数:20 $playerUidD 分数:30 游戏3 我想运行一个查询,返回所有游戏节点,其中每个游戏节点(玩家)的子节点将根据得分进行排序。游戏节点包含每个玩家的UID,每个UID节点包含玩家的分数。我也在存储其他数据,但是,为了这个例子,我将只使用分数 我可以用一个查询来完成吗?差不多 roo

考虑到Firebase数据库的以下结构:

    • 游戏1
      • $playerUidA
        • 分数:50
      • $playerUidB
        • 分数:10
    • 游戏2
      • $playerUidC
        • 分数:20
      • $playerUidD
        • 分数:30
    • 游戏3
我想运行一个查询,返回所有游戏节点,其中每个游戏节点(玩家)的子节点将根据得分进行排序。游戏节点包含每个玩家的UID,每个UID节点包含玩家的分数。我也在存储其他数据,但是,为了这个例子,我将只使用分数

我可以用一个查询来完成吗?差不多
rootRef.child(“root”).orderByChild(“score”)
?不幸的是,这似乎不起作用

或者实现这一点的唯一方法是在客户端上手动排序项目


@Puf-希望你能回答:)

如果你想让所有游戏按玩家得分排序,你需要做的就是使用你的
.indexOn
规则

{
  "rules": {
    "$gameId": {
      ".indexOn": "score",
      "$playerUid": {
        ...  
      }
    }
  }
}
这将使您的数据在数据库中保持排序,因此当您检索数据时,您将准备好所有数据。但是请记住,如果您想要检索所有游戏和所有玩家,这意味着您将获取整个数据库。因此,您应该考虑应用程序的需求,并重新考虑其结构

在缩放时,可以使用
firebase.database().ref(gameId).limitToLast(10)
在游戏中迭代并检索有限数量的用户

更新

对于您的示例,您将拥有具有以下请求的所有游戏:

firebase.database().ref().once('value', snap => {
    //prints all players for each game sorted ascending.
    snap.forEach(game => {
        game.forEach(player => {
            console.log(player.val());
        });
    });
});

虽然这个问题已经很老了,但可能会有人(像我一样)被它绊倒。特别是因为它是非常直观的结构数据库,以类似的方式,作者的问题,创建(例如)一个排行榜系统的游戏。由于答案有点过时,我想补充一些东西

不久前,开发人员增加了通过深度嵌套的孩子进行订购的可能性!(请参阅)要做到这一点,您基本上必须做与作者完全相同的事情,并额外使用@adolfosrs给出的答案的第一部分。基本上你必须做两件事:

  • 使用
    .indexOn
    (如@adolfosrs所述)
  • 使用
    OrderByChild()
    命令
  • 要对@steliosf给出的示例进行此操作,您必须执行以下操作:

    首先在数据库规则中设置.indexOn:

    {
      "rules": {
        "$gameId": {
          ".indexOn": "score",
          "$playerUid": {
            ...  
          }
        }
      }
    }
    
    Second使用问题作者已经使用过的命令:

    rootRef.Child("root").OrderByChild("score")
    
    我建议您始终添加LimitToFirst()或LimitToLast()命令,以避免拉取可能包含大量数据的整个数据库(当然,这取决于数据库的大小)。例如,要获得前10名分数,您可以使用:

    rootRef.Child("root").OrderByChild("score").LimitToLast(10)
    

    由于数据是按升序排列的,因此您需要使用LimitToLast()。

    我在数据库规则中使用
    “.indexOn:“score”
    ,我可以检索单个游戏节点,其中玩家按分数排序。问题是,我无法检索所有游戏节点,其中每个游戏节点都将按照分数对其子节点(玩家)进行排序。这不能通过单个查询完成。我必须为每个游戏节点运行不同的查询,或者手动对客户端上的子节点进行排序。当然,我不是想获取整个数据库,结构只是一个例子。嘿@MScott,它有用吗?如果您还有任何疑问,请告诉我。谢谢您的建议@adolfosrs。遗憾的是,玩家没有在游戏父节点上通过单个查询进行排序。最后,我在for循环中为每个游戏节点运行了一个查询,这很有效,但这并不是我想要的最佳解决方案。但似乎没有其他解决办法。要么是这样(多个查询),要么是在游戏父节点上运行一个查询,然后在客户端上手动排序每个游戏节点的子节点。