Firebase数据库 - 如何构建祖先树

时间:2016-06-02 11:40:32

标签: firebase firebase-realtime-database

假设我们有三种不同的类型,GreatGrandmaGrandmaMom。所以你可能想象他们的祖先关系就像这样。

 - 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节点的访问权限。

1 个答案:

答案 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. 
       }
     })
   }
})