web-dev-qa-db-ja.com

Firebase Query Double Nested

Firebaseの以下のデータ構造を考えると、ブログ「efg」を取得するクエリを実行したいと思います。この時点でユーザーIDがわかりません。

{Users :
     "1234567": {
          name: 'Bob',
          blogs: {
               'abc':{..},
               'zyx':{..}
          }
     },
     "7654321": {
          name: 'Frank',
          blogs: {
               'efg':{..},
               'hij':{..}
          }
     }
}
26
Chris Raheb

Firebase APIでは、orderByChildメソッドとequalToメソッドを使用して、1レベルの深さ(または 既知のパス )の子のみをフィルタリングできます。

したがって、現在のデータ構造を変更/拡張せずに、すべてのデータを取得してクライアント側でフィルタリングするオプションを残すだけです。

var ref = firebase.database().ref('Users');
ref.once('value', function(snapshot) {
    snapshot.forEach(function(userSnapshot) {
        var blogs = userSnapshot.val().blogs;
        var daBlog = blogs['efg'];
    });
});

もちろん、これは非常に非効率的であり、重要な数のユーザー/ブログがある場合には拡張できません。

そのための一般的な解決策は、探しているキーをそれが存在するパスにマップする、いわゆるツリーのインデックスに対するものです。

{Blogs:
     "abc": "1234567",
     "zyx": "1234567",
     "efg": "7654321",
     "hij": "7654321"
}

次に、以下を使用してブログにすばやくアクセスできます。

var ref = firebase.database().ref();
ref.child('Blogs/efg').once('value', function(snapshot) {
    var user = snapshot.val();
    ref.child('Blogs/'+user+'/blogs').on('value, function(blogSnapshot) {
        var daBlog = blogSnapshot.val();
    });
});

また、ユースケースとFirebaseの制限により合うようにデータを再構築できるかどうかを再検討することもできます。データの構造化に関するいくつかの優れたドキュメントがありますが、NoSQL /階層データベースを初めて使用する人にとって最も重要なドキュメントは "ネストの構築を避ける" のようです。

良い例については、 child of childに値が含まれている場合のFirebaseクエリ に関する私の回答も参照してください。また、 Firebaseの多対多の関係 、および一般的なこの記事 NoSQLデータモデリング について読むことをお勧めします。

32

現在のデータ構造を指定すると、探しているブログ投稿を含むユーザーを取得できます。

const db = firebase.database()
const usersRef = db.ref('users')
const query = usersRef.orderByChild('blogs/efg').limitToLast(1)
query.once('value').then((ss) => {
  console.log(ss.val()) //=> { '7654321': { blogs: {...}}}
})

limitToLastdocs を使用する場合、オブジェクトは最後にソートされるため、orderByChildを使用する必要があります。

1
Bryan Massoth

実際には非常に簡単です-フォアスラッシュを使用するだけです:

db.ref('Users').child("userid/name")
db.ref('Users').child("userid/blogs")
db.ref('Users').child("userid/blogs/abc")

ループなどは必要ありません。

0
Nyagolova