2016-09-12 1 views
1

私はデータベースとしてFirebaseを使用してリーダーボードアプリを作成しています。私は古い学校のSQLのバックグラウンドから来たので、この新しいnoSQLタイプのデータベースはデータベースのキーと参照の不安を与えています。Firebaseリーダーボード、最適なインプリメント。 SQL結合とorderby

メンバーがある各グループには、さまざまなテストのスコアがあります。特定のテストのスコアが順番に表示されるグループのデータを取得する最も効率的な方法は何ですか。 SQLではこれは明らかにjoinとorderbyを使用することは自明ですが、これまでのFirebaseのドキュメントでは、効率的にクエリを実行して結合データのブロックを取得する方法を試すことができません

私の現在解決策は以下の通りですが、クライアント側ですべての並べ替えを実行する必要があります。私は現在、グループのすべてのユーザーを取得し、各ユーザーのテストスコアの個々のレコードを取得するために繰り返します。私は、日付にかかわらず、与えられたテストのために単一の最高得点を取得する必要があります。

var testName = 'test1'; 
var scores = firebase.database().ref('/groupMembers/' + 'TestGroup').once('value').then(function(snapshot) { 
       console.log(snapshot.val()); 
       for(var user in snapshot.val()){ 
        //...query the database for each separate users score on test1 
       } 
      //sort the test scores here on client side js 
      }); 

データベース設計のヒントは、どちらもうまくいきません。私は、あなたは間違いなく正しい道を下って行くと思います

groupMembers{ 
    TestGroup{ 
     user1 : true 
     user2 : true 
    } 
} 

testScores{ 
    user1{ 
     test1{ 
     date : 11/04/2016 
     score : 90 
     } 
    test1{ 
     date : 05/07/2016 
     score : 100 
     } 
    test2{ 
     date : 11/06/2016 
     score : 50 
     } 
    } 
    user2{ 
     test1{ 
     date : 15/04/2016 
     score : 70 
     } 
    test2{ 
     date : 05/07/2016 
     score : 80 
     } 
    test2{ 
     date : 11/10/2016 
     score : 50 
     } 
    } 
} 

おかげ

答えて

1

。ビットの周りにあなたのデータを変更するため申し訳ありませんが、あなたが同じ名前(第2の最初のユーザとTEST2でTEST1)との2つのキーを持つことができますが、私はこのようなあなたのデータを保存する方法をわからない:

{ 
    groupMembers : { 
     TestGroup : { 
      tests : { 
       test1 : true, 
       test2 : true 
      }, 
      users : { 
       user1 : true 
       user2 : true 
      } 
     } 
    }, 
    userTestScores : { 
     user1 : { 
      test1 : true, 
      test2 : true 
     }, 
     user2 : { 
      test1 : true, 
      test2 : true 
     } 
    }, 
    testScores : { 
     test1 : { 
      users : { 
       user1: { 
        date : "11/04/2016" 
        score : 90 
       }, 
       user2: { 
        date : "15/04/2016" 
        score : 70     
       } 
      } 
     }, 
     test2: { 
      users: { 
       user1: { 
        date : "11/06/2016" 
        score : 50 
       }, 
       user2: { 
        date : "05/07/2016" 
        score : 80    
       } 
      } 
     } 
    } 
} 

をとその後、あなたのクエリは、テストグループのすべてのテストを見つけることであろうと、あなたは簡単にあなたが頻繁にあなたがそれにアクセスする方法のためにデータをモデル化するのNoSQLで最高得点は

firebase.database().ref('/groupMembers/TestGroup/tests').once('value').then(function (snapshot) { 
    for (var test in snapshot.val()) { 
     firebase.database().ref('/groupMembers/testScores/tests/' + test + '/users/').orderByChild('score').limitToLast(1).once('value').then(function (snapshot) { 
      //highest score will be here 
     }); 
    } 
}); 
+0

華麗これは私がのためにのために目指していたものです! –

2

を見つけることができます。私はこの記事をNoSQL data modelingで読むことを強くお勧めします。

あなたの質問が正しく理解されている場合は、そのグループのトップスコアユーザーを含む特定のグループのリーダーボードを表示する必要があります。 Firebaseクエリで、あなたはこのデータモデルを使用できることを行うには:

groupScores: { 
    TestGroup: { 
    user1: { // the highest score for user1 
     test: "test1" 
     date : 05/07/2016 
     score : 100 
    } 
    user2: { // the highest score for user2 
     test: "test2" 
     date : 05/07/2016 
     score : 80 
    } 
    } 
} 

をだから私は、このモデルでは、各ユーザーのための唯一の最高のスコアを維持することを、関係なくはどのようなテストにユーザーがいることを持っていないだろうスコア。この方法では、各ユーザーはリーダーボードに1回しか表示できません。ユースケースが異なる場合は、データを異なる方法でモデル化する必要があります。

あなたがリーダーボードを得ることができ、このデータ構造により

var query ref.child('groupScores/TestGroup').orderByChild('score').limitToLast(10); 
query.on('value', function(snapshot) { 
    // TODO: loop over children, invert them, show leaderboard 
});