Firebase查询双嵌套

Chr*_*heb 27 firebase firebase-realtime-database

鉴于firebase中的数据结构,我想运行一个查询来检索博客'efg'.我此时不知道用户ID.

{Users :
     "1234567": {
          name: 'Bob',
          blogs: {
               'abc':{..},
               'zyx':{..}
          }
     },
     "7654321": {
          name: 'Frank',
          blogs: {
               'efg':{..},
               'hij':{..}
          }
     }
}
Run Code Online (Sandbox Code Playgroud)

Fra*_*len 32

在火力地堡API只允许您过滤孩子深一级(或用已知的路径与它)orderByChildequalTo方法.

因此,无需修改/扩展当前的数据结构,只留下检索所有数据的选项并在客户端过滤它:

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

这当然是非常低效的,并且当您拥有非平凡数量的用户/博客时将无法扩展.

因此,通常的解决方案是对树的所谓索引,将您要查找的密钥映射到它所在的路径:

{Blogs:
     "abc": "1234567",
     "zyx": "1234567",
     "efg": "7654321",
     "hij": "7654321"
}
Run Code Online (Sandbox Code Playgroud)

然后您可以使用以下方式快速访问博客:

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();
    });
});
Run Code Online (Sandbox Code Playgroud)

如果您可以重新构建数据以更好地适应您的用例和Firebase的限制,您可能还需要重新考虑.他们有一些关于构建数据的好文档,但对于NoSQL /层次数据库新手来说,最重要的一个似乎是"避免构建嵌套".

如果子项的子项包含一个好的示例,请参阅我对Firebase查询的回答.我还建议阅读Firebase中的多对多关系,以及关于一般NoSQL数据建模的这篇文章.

  • 请注意,[深度查询](https://www.firebase.com/blog/2015-09-24-atomic-writes-and-more.html)现在是一项功能. (17认同)
  • 我不认为深层次的查询可以解决问题; 但帖子声明你只能查询一级深度,这不再是真的. (4认同)
  • 我已经考虑了几分钟,但放弃了:深层查询将如何解决这个问题? (3认同)
  • @FrankvanPuffelen,我最近一直在阅读你的很多答案(你似乎是唯一一个对firebase有所了解的人[看你是如何成为一名firebase工程师])而且我想知道你是否最终解决了你的问题答案是一种最佳做法,还是我们应该总是试图使信息结构化,以便我们只能打一个电话? (3认同)