Reputation: 2734
I'm struggling with how to model one-to-many and many-to-many relations in a NoSQL database like Firestore. I want to model Teachers, Pupils, and Classes: a Pupil is part of at least one class, a Teacher can teach multiple classes. In a relation database, this would probably result in the following tables (I'm no database expert at all)
I want to be able to do the following queries:
But what is the idiomatic way to model this in NoSQL, eg Firestore? I've read that joins are not available in NoSQL and that data duplication is not uncommon in NoSQL but I'm confused as to how the database structure would look like.
Upvotes: 1
Views: 88
Reputation: 138834
Since we are structuring a Firestore database according to the queries that we intend to perform, for the following queries:
Please check the following schema:
Firestore-root
|
--- classes (collection)
| |
| --- $classId (document)
| |
| --- id: "classId"
| |
| --- name: "ClassName"
| |
| --- pupils (array)
| |
| --- 0: "pupilId"
| |
| --- 1: "pupilId"
|
--- teachers (collection)
| |
| --- $teacherId (document)
| |
| --- id: "classId"
| |
| --- name: "TeacherName"
| |
| --- phone: "+000..."
| |
| --- email: "[email protected]"
| |
| --- classes (array)
| |
| --- 0: "classId"
| |
| --- 1: "classId"
|
--- pupils (collection)
|
--- $pupilId (document)
|
--- id: "pupilId"
|
--- name: "PupilName"
|
--- teachers (array)
|
--- 0: "teacherId"
|
--- 1: "teacherId"
I'll write the queries in Java, but it simply can be translated into other programming languages too.
Considering the following rootRef:
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
And the following collection references:
CollectionReference classesRef = rootRef.collection("classes");
CollectionReference teachersRef = rootRef.collection("teachers");
CollectionReference pupilsRef = rootRef.collection("pupils");
#1. To get the pupils that exist in a class, you have to create a reference to that particular class:
DocumentReference classIdRef = classesRef.document(classId);
classIdRef.get().addOnCompleteListener(/* ... /*);
Download the document, and get all pupil IDs that exist in the "pupils" array. Then for each pupil ID, create a new reference:
DocumentReference pupilIdRef = classesRef.document(pupilId);
And get their corresponding data.
#2. In the same way, we did above, do it also in the case of teachers. Get the classes from the array and create a separate database call for each class to get the corresponding data.
#3. Same as before.
Upvotes: 1