从Firestore中选择随机文档

CLI*_*P Y 5 java android firebase google-cloud-firestore

我在Cloud Firestore的单个集合中有1000个文档,是否可以提取随机文档?

举例来说:Students是Firestore中的一个集合,我有1000个学生,我的要求是每次通话随机选择10个学生。

Ale*_*amo 1

是的,要实现这一点,请使用以下代码:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference studentsCollectionReference = rootRef.collection("students");
studentsCollectionReference.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            List<Student> studentList = new ArrayList<>();
            for (DocumentSnapshot document : task.getResult()) {
                Student student = document.toObject(Student.class);
                studentList.add(student);
            }

            int studentListSize = studentList.size();
            List<Students> randomStudentList = new ArrayList<>();
            for(int i = 0; i < studentListSize; i++) {
                Student randomStudent = studentList.get(new Random().nextInt(studentListSize));
                if(!randomStudentList.contains(randomStudent)) {
                    randomStudentList.add(randomStudent);
                    if(randomStudentList.size() == 10) {
                        break;
                    }
                }
            }
        } else {
            Log.d(TAG, "Error getting documents: ", task.getException());
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

这称为经典解决方案,您可以将其用于仅包含少量记录的集合,但如果您担心获得大量读取,那么我会推荐您第二种方法。这还涉及到对数据库进行一点更改,添加一个新文档,该文档可以保存包含所有学生 ID 的数组。因此,要获取这 10 个随机学生,您只需要进行一次get()调用,这意味着只需一次读取操作。获得该数组后,您可以使用相同的算法并获得这 10 个随机 id。一旦你有了这些随机 ID,你就可以获取相应的文档并将它们添加到列表中。通过这种方式,您只需再执行 10 次读取即可获得实际的随机学生。总共只有 11 个文档读取。

这种做法称为非规范化(重复数据),是 Firebase 的常见做法。如果您是 NoSQL 数据库的新手,为了更好地理解,我建议您观看此视频,非规范化在 Firebase 数据库中是正常的。它适用于 Firebase 实时数据库,但相同的原则也适用于 Cloud Firestore。

但请记住,在这个新创建的节点中添加随机产品的方式,就像您需要在不再需要时删除它们一样。

要将学生 ID 添加到数组中,只需使用:

FieldValue.arrayUnion("yourArrayProperty")
Run Code Online (Sandbox Code Playgroud)

要删除学生 ID,请使用:

FieldValue.arrayRemove("yourArrayProperty")
Run Code Online (Sandbox Code Playgroud)

要一次获取所有 10 名随机学生,您可以使用List<Task<DocumentSnapshot>>然后调用Tasks.whenAllSuccess(tasks),如我在这篇文章中的回答中所述:

  • 它的记忆效率不高。如果我只想要 10 个文档,为什么它检索到的可能是 1000 个。 (6认同)