39

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

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

3 回答 3

38

Firebase 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'];
    });
});

这当然是非常低效的,并且当您拥有大量用户/博客时不会扩展。

因此,常见的解决方案是为您的树创建一个所谓的索引,将您正在寻找的键映射到它所在的路径:

{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').once('value', function(blogSnapshot) {
        var daBlog = blogSnapshot.val();
    });
});

您可能还想重新考虑是否可以重组数据以更好地适应您的用例和 Firebase 的限制。他们有一些关于构建数据的很好的文档,但是对于刚接触 NoSQL/分层数据库的人来说,最重要的文档似乎是“避免筑巢”

如果子项的子项包含一个很好的示例值,请参阅我对 Firebase 查询的回答。我还建议阅读Firebase 中的多对多关系以及有关通用NoSQL 数据建模的文章。

于 2014-11-29T23:53:58.023 回答
2

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

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时对象是最后排序的。

于 2018-06-20T17:46:21.820 回答
1

这实际上非常简单 - 只需使用前斜杠:

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

不需要循环或其他任何东西。

于 2019-08-23T12:45:43.210 回答