假设我们有三种不同的类型,GreatGrandma
,Grandma
和Mom
。所以你可能想象他们的祖先关系就像这样。
- GreatGrandma
- Grandma
- Mom
由于我们不希望将整个数据嵌套在一个JSON树中,因为它太大了,我们可能会认为结构化看起来像这样。
"greatGrandmas": {
"$great_grandma_key": {
"name": "Jane Smith",
"birthDate": "1970-01-01"
}
}
"grandmas": {
"$great_grandma_key": {
"$grandma_key": {
"name": "Jane Smith",
"birthDate": "1970-01-01"
}
}
}
"moms": {
"$great_grandma_key": {
"$grandma_key": {
"$mom_key": {
"name": "Jane Smith",
"birthDate": "1970-01-01"
}
}
}
}
现在让我们说我们想查询妈妈们。如果我们知道GreatGrandma和奶奶那很容易。
firebase.database()
.ref('moms')
.child(greatGrandmaKey)
.child(grandmaKey);
.on('child_added', function (snapshot) { ... });
然后我们可以添加大小限制或等于过滤器。
但是,让我们说我们希望得到所有妈妈类型的某个GreatGrandma。我们可以做到以下几点。
firebase.database()
.ref('moms')
.child(greatGrandmaKey)
.on('value', function (snapshot) { ... });
但是我们无法在此处应用任何过滤器。我们将被迫获取整个数据。这不可扩展。
如何构建firebase数据库,以便查询具有完整或部分祖先路径的子项?
此外,我希望能够限制对整个树的访问,并且只授予对某些Mom节点的访问权限。
答案 0 :(得分:2)
在moms部分的示例中,您仍然在创建一个深度节点关系,这就是为什么您无法在mom节点中进行高效查询的原因,即使您只需要一小部分数据,也会得到大的子响应有很多方法可以实现你想要的,有两种选择:
你可以为每种类型设置这样的引用,以便能够只调用你在这种情况下需要的信息数据或类型的子项,如果你想在上游和下游找到关系,这将会很有帮助:
"greatGrandmas": {
"$great_grandma_key": {
"data":{
"name": "Jane Smith",
"birthDate": "1970-01-01",
},
"grandmas":{
"$grandma_key":true
},
"moms":{
"$mom_key":true
}
}
}
"grandmas": {
"$grandma_key": {
"data":{
"name": "Jane Smith",
"birthDate": "1970-01-01",
},
"great_grandmas":{
"$great_grandma_key":true
},
"moms":{
"$mom_key":true
}
}
}
"moms": {
"$mom_key": {
"data":{
"name": "Jane Smith",
"birthDate": "1970-01-01",
},
"great_grandmas":{
"$great_grandma_key":true
},
"grandmas":{
"$grandma_key":true
}
}
}
如果你只想找到最低节点的关系,在这种情况下妈妈和祖母你可以做这样的事情:
moms:{
"$mom_key": {
"name": "Jane Smith",
"birthDate": "1970-01-01"
"great_grandma":$great_grandma_key
"grandma":$grandma_key
}
}
grandmas:{
"$grandma_key": {
"name": "Jane Smith",
"birthDate": "1970-01-01"
"great_grandma":$great_grandma_key
}
}
great_grandmas:{
"$great_grandma_key": {
"name": "Jane Smith",
"birthDate": "1970-01-01"
}
}
在这种情况下,您只能通过特定的子节点值来查询以获取关系,但它只是上游。
这取决于您将如何查询和读取数据,谁将拥有访问权限以及易于访问-vs之间的平衡 - 保持数据库一致的复杂性
查询将如下:
REF_TO_MOM.orderByChild(' grandma')。equalTo($ grandma_key).on(' child_added',callback)
这个人会得到同一个奶奶的妈妈
这里是查询类型的参考以及如何使用它们
https://firebase.google.com/docs/database/android/retrieve-data#filtering_data
要获得与第一个结构相同的结果,您可以执行此操作:
MOMS_REF.child($mom_key).child('grandmas').on('child_added',function(snapshot){
//Here you only have the key of the mom's grandma so you can call a single event listener to get the rest of the data , this is a fairly common practice in firebase with very low network and data cost, to keep the data flow efficient i grouped the properties under a "data" node to avoid bringing unnecessary children in this call
GRANDMA_REF.child(snapshot.key).child('data').once('value',function(snap){
if(snap.val()){
//Here you can append to a dictionary or array the name, birthDate and the key of the grandmas of one mom.
}
})
}
})