2016-06-02 3 views
1

Предположим, у нас есть три разных типа: GreatGrandma, Grandma и Mom. Так как вы, вероятно, предположили, что их отношения с предками выглядят так.База данных Firebase - Как структурировать родовое дерево

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

Мы могли бы затем добавить ограничение по размеру или равный фильтр.

Но скажем, мы хотим получить все типы мамы для определенной Великой Грэндмы. Мы могли бы сделать следующее.

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

Однако мы не сможем применить фильтры здесь. Мы будем вынуждены получить все данные. Это не масштабируется.

Как я могу создать базу данных firebase, чтобы я мог запрашивать детей с полным или частичным путем предков?

Кроме того, я хочу иметь возможность ограничивать доступ ко всему дереву и предоставлять доступ только определенным узлам Mom.

+0

Это хороший прецедент для базы данных графов, на которую я верю. –

+0

@AliGajani Вы могли бы быть более конкретным? В частности, опишите, как это может выглядеть в Firebase? –

ответ

2

В вашем примере в части мамы вы по-прежнему создаете глубокое отношение к узлу, поэтому вы не можете делать эффективные запросы в узле мамы, и вы получите большие ответы на сына, даже если вам нужна небольшая часть данных, есть много способов добиться того, чего вы хотите, пара вариантов:

Вы можете установить для этого типа ссылки, подобные этому, чтобы иметь возможность вызывать только необходимую вам информацию в этом случае данных или детей типа, это было бы полезно, если вы хотите найти в отношениях вверх и вниз по течению:

"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).на («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. 
     } 
    }) 
    } 
}) 
+0

Не могли бы вы показать некоторые примеры того, как будут выглядеть запросы? –

+0

Обновлено, с запросом, который работает для второго примера структуры, первая структура не требует запросов, которые вам нужны только для ссылок на пути, такие как MOMS_REF.child ('grandma'). On ('child_added', callback) – Ymmanuel

+0

Этот вопрос я понял. Как бы вы получили те же результаты, если база данных была структурирована в первую очередь? –

Смежные вопросы