I'm using firebase as my database-backend and have a many to many relationship. As my relationship is a little bit more abstract I'll go with a simplified example here. Let's say we have students and lectures. Students can attend lectures and lectures have a list of attending students. Throughout the application, both queries are needed, so that there is no real advantage of keeping the list in either one of them. This issue seems not uncommon in No-SQL scenarios like this and I've even read about storing a list of all lectures for each student and a list of students for each lecture, being a valid solution. So lets say my JSON data looks like this:
"students": {
"s1" : {
"name": "A",
"lectures": ["l1", "l2"]
},
"s2" : {
"name": "B",
"lectures": ["l2", "l3"]
}
}
and
"lectures": {
"l1" : {
"title": "lecture1",
"students": ["s1"]
},
"l2" : {
"title": "lecture2",
"students": ["s1", "s2"]
},
"l3" : {
"title": "lecture3",
"students": ["s2"]
}
}
With s1, s2, l1, l2, l3 being the cryptic Firebase IDs. Using a setup like this, it is easy to write a query in order to get all lectures of student "s1" as an array ["l1", "l2"].
However, I can't figure out how to get the corresponding lecture elements using this set of IDs, as I can only query for one ID. I also want to avoid fetching all data and filtering it afterwards using Java-Code.
This would do the trick:
Firebase ref = new Firebase("https://stackoverflow.firebaseio.com/35963762");
ref.child("students/s1/lectures").addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot lessonKey: snapshot.getChildren()) {
ref.child("lectures").child(lessonKey.getValue(String.class)).addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot lectureSnapshot) {
System.out.println(lectureSnapshot.child("title").getValue());
}
public void onCancelled(FirebaseError firebaseError) {
}
});
}
}
public void onCancelled(FirebaseError firebaseError) {
}
});
Output:
lecture1
lecture2
A few remarks on your data structure though:
You are nesting data structure that should likely not be nesting. For example this code now also load the students
list of lecture1 and lecture2, which it doesn't need. If you move the "students in a lecture" and "lectures for a student" into their own top-level nodes you won't have this problem.
You store the "students in a lecture" in an array. This means that if you remove a lecture from the middle of the array, you will have to update all of the ones after it. The more common approach is to store the lecture id as the key and a dummy true
as the value:
students_per_lecture: {
"l2" : {
"s1": true,
"s2": true
}
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With