我使用firebase作为我的数据库后端,并且有很多关系。 由于我的关系有点抽象,我将在这里提供一个简化的例子。假设我们有学生和讲座。学生可以参加讲座和讲座,有一份参加学生的名单。在整个应用程序中,需要两个查询,因此没有真正的优势将列表保留在其中任何一个中。这个问题在像这样的No-SQL场景中似乎并不罕见,我甚至已经阅读过关于为每个学生存储所有讲座的列表以及每个讲座的学生列表,这是一个有效的解决方案。 所以我要说我的JSON数据如下所示:
"students": {
"s1" : {
"name": "A",
"lectures": ["l1", "l2"]
},
"s2" : {
"name": "B",
"lectures": ["l2", "l3"]
}
}
和
"lectures": {
"l1" : {
"title": "lecture1",
"students": ["s1"]
},
"l2" : {
"title": "lecture2",
"students": ["s1", "s2"]
},
"l3" : {
"title": "lecture3",
"students": ["s2"]
}
}
s1,s2,l1,l2,l3是神秘的Firebase ID。 使用这样的设置,可以很容易地编写查询,以便将学生“s1”的所有讲座作为数组[“l1”,“l2”]。
但是,我无法弄清楚如何使用这组ID获取相应的讲座元素,因为我只能查询一个ID。 我还想避免获取所有数据并在之后使用Java代码对其进行过滤。
答案 0 :(得分:6)
这样可以解决问题:
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) {
}
});
输出:
lecture1
lecture2
虽然对您的数据结构有一些评论:
您正在嵌套可能不会嵌套的数据结构。例如,此代码现在还加载了讲座1和讲座2的students
列表,它不需要。如果您将“演讲中的学生”和“学生讲座”移到他们自己的顶级节点中,您将不会遇到此问题。
您将“学生在演讲中”存储在一个数组中。这意味着如果从阵列中间删除讲座,则必须更新后面的所有讲座。更常见的方法是将讲座ID存储为密钥,将虚拟true
存储为值:
students_per_lecture: {
"l2" : {
"s1": true,
"s2": true
}
},