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

Firebase Database - How to structure ancestral tree

假设我们有三种不同的类型,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"
            }
        }
    }       
}          

现在假设我们要查询妈妈。如果我们知道曾祖母和曾祖母就容易了。

firebase.database()
        .ref('moms')
        .child(greatGrandmaKey)
        .child(grandmaKey);
        .on('child_added', function (snapshot) { ... });

然后我们可以添加大小限制或 equalTo 过滤器。

但是假设我们想要获取某个曾祖母的所有妈妈类型。我们可以执行以下操作。

firebase.database()
        .ref('moms')
        .child(greatGrandmaKey)
        .on('value', function (snapshot) { ... });

但是我们无法在此处应用任何过滤器。我们将被迫获取全部数据。这是不可扩展的。

如何构建一个 firebase 数据库,以便我可以使用完整或部分祖先路径查询 children?

此外,我希望能够限制对整个树的访问,并且只授予对某些 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"
 }
}

在这种情况下,您只能通过特定的子节点值查询来获取关系,但它只会在上游。

这取决于您将如何查询和读取数据、谁将有权访问以及在易于访问与保持数据库一致的复杂性之间取得平衡

查询如下:

REF_TO_MOM.orderByChild('grandma').equalTo($grandma_key).on('child_added',回调)

这个会让所有的妈妈和同一个奶奶在一起

这里是查询类型的引用以及如何使用它们

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