Firebase - 通过 ID 列表获取元素

Firebase - get elements by list of IDs

我使用 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来获取相应的lecture元素,因为我只能查询一个ID。 我还想避免获取所有数据并在之后使用 Java-Code.

对其进行过滤

这样做就可以了:

Firebase ref = new Firebase("https://Whosebug.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

关于您的数据结构的几点说明:

  • 您正在嵌套不应该嵌套的数据结构。例如,此代码现在还加载它不需要的 lecture1 和 lecture2 的 students 列表。如果您将 "students in a lecture" 和 "lectures for a student" 移动到它们自己的顶级节点中,您将不会遇到此问题。

  • 您将 "students in a lecture" 存储在一个数组中。这意味着如果你从数组中间删除一个讲座,你将不得不更新它后面的所有讲座。更常见的方法是将讲座 ID 存储为键,将虚拟 true 存储为值:

    students_per_lecture: {
      "l2" : {
        "s1": true, 
        "s2": true
      }
    },