Reputation: 757
I'm designing a firestore database, trying to understand no-sql. What's getting me stuck is relationships. I know I'm supposed to keep root level collections and relate them with references, but I don't understand how to manage the relations once the data is on the client. Say this is my data (without relations) ...
Schools (collection)
JFKElementary (doc)
address: 123 Elm Street
Classrooms (collection)
Room1 (doc)
roomNumber: 1
Room2 (doc) ...
Families (collection)
Jones.1234 (doc)
address: 456 Cherry Lane
Smith.2134 (doc) ...
Students
Billy.Jones.2323 (doc)
name: Billy Jones
I need to represent the idea that "Billy Jones" belongs to the Jones.1234
family, and that he belongs to the Room1
classroom, and that the classroom and the family belong to the JFKElementary
school. I know I can place refs in the documents, like this...
Classrooms (collection)
Room1 (doc)
roomNumber: 1
school: ref to JFK Elementary
Students
Billy.Jones.2323 (doc)
name: Billy Jones
family: ref to Jones.1234
classroom: ref to Room1
school: ref to JFK Elementary
I want to get a whole school on the client, so I think I can query like this:
collection('classrooms').where("school", "==", <school ref>)
collection('students').where("school", "==", <school ref>)
// etc for families
That gets me the whole school, but leaves my problem: On the client, how do I assemble the relationships that UI needs? For example, say the UI wants to present the names of all the students in Room1...
let room1 = classroomsSnapshot.docs[0]
let room1Students = studentsSnapshot.docs.filter(student => {
return student.data().classroom.id === room1.id
})
I wouldn't want all that code run each time I need a room's students. I could build my own class on the client like this?
class ClientSideClassroom {
constructor(doc, studentsSnapshot) {
this.doc = doc
this.students = studentsSnapshot.docs.filter(student => {
return student.data().classroom.id === room1.id
})
}
and on a snapshot...
let clientClassrooms = classroomsSnapshot.docs().map(doc => {
return new ClientSideClassroom(doc, studentsSnapshot)
})
If so, then the student docs (and all of the others) are going to need their own class, too, e.g. to answer the ClientSideClassroom
to which they belong. Do I now have to keep two objects for every firestore doc? The "real" one and a wrapper that keeps the relations?
Even if I have forward pointers on the collections, I don't think that puts me ahead. e.g.
Classrooms (collections)
Room1 (doc)
students: [ref to Billy.Jones.123, ...
I wouldn't query that classrooms' students with get
s, because I got the whole collection in a students query. But I still need to turn the students array into an array of actual docs, not refs....
// ClientSideClassroom class constructor
this.students = this.doc.data().students.map(studentRef => {
return // find the student in the studentsSnapshot with studentRef
})
Am I going about this all wrong?
Upvotes: 1
Views: 179
Reputation: 460
Put all student name inside classA document. - you can get all student name on specific class. classCollection will have a lot doc such as classA, classB, classC
Put all family member name inside familyJones doc - you can get all family member name on one family doc
On user jones document, put all his detail such as class, family, school, home address inside one doc
This video will help u https://youtu.be/v_hR4K4auoQ
Upvotes: 1