Firebase查询双嵌套

时间:2014-11-29 21:00:07

标签: firebase firebase-realtime-database

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

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

3 个答案:

答案 0 :(得分:29)

Firebase API仅允许您使用orderByChildequalTo方法过滤一级深度(或with a known path)的儿童。

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

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 /层次数据库新手来说,最重要的文档似乎是"avoid building nests"

另请参阅Firebase query if child of child contains a value上的答案,以获得一个好例子。我还建议您阅读many-to-many relationships in Firebase,以及有关一般NoSQL data modeling的文章。

答案 1 :(得分:1)

鉴于您当前的数据结构,您可以检索包含您要查找的博客文章的用户。

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: {...}}}
})

您需要使用limitToLast,因为使用orderByChild docs时,对象是最后排序的。

答案 2 :(得分:0)

实际上超级简单-只需使用前划线:

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

无需循环或其他任何操作。