我在Cloud Firestore的单个集合中有1000个文档,是否可以获取随机文档?
比如说:Students
是Firestore中的一个集合,我在该集合中有1000名学生,我的要求是在每次通话时随机挑选10名学生。
答案 0 :(得分: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<Students> studentList = new ArrayList<>();
for (DocumentSnapshot document : task.getResult()) {
Student student = document.toObject(Student.class);
studentList.add(student);
}
int studentCount = studentList.size();
int randomNumber = new Random().nextInt(studentCount);
List<Students> randomStudentList = new ArrayList<>();
for(int i = 1; i < 10; i++) {
randomStudentList.add(studentList.get(randomNumber));
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
答案 1 :(得分:1)
根据Alex's answer,我得到了从Firebase Firestore数据库中获取重复记录的提示(特别是少量数据)
我在他的问题中遇到了一些问题,如下:
do $$
declare selectrow record;
begin
for selectrow in
select 'ALTER TABLE '|| T.mytable || ' ADD COLUMN x_is_exported boolean DEFAULT FALSE' as script
from (select tablename as mytable from pg_tables where schemaname ='public') t
loop
begin
execute selectrow.script;
EXCEPTION WHEN duplicate_column THEN CONTINUE;
END;
end loop;
end;
$$;
相同的所有记录,而不会更新。randomNumber
,最终列表中的记录也可能重复。我将答案更新如下:
randomNumber
希望这种逻辑对所有数据量少的人有帮助,我认为这不会对1000到5000个数据造成任何问题。
谢谢。
答案 2 :(得分:0)
Alex Mamo描述的第二种方法看起来与此类似:
在下面的代码中,您从数组中获得3个随机且唯一的字符串,并将其存储在列表中,您可以从中访问字符串并进行查询。我正在片段中使用此代码:
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_category_selection, container, false);
btnNavFragCat1 = view.findViewById(R.id.btn_category_1);
btnNavFragCat1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
questionKeyRef.document(tvCat1).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
List<String> questions = (List<String>) document.get("questions"); // This gets the array list from Firestore
List<String> randomList = getRandomElement(questions, 0);
removeDuplicates(randomList);
...
}
}
});
}
});
...
return view;
}
private List<String> getRandomElement(List<String> list, int totalItems) {
int PICK_RANDOM_STRING = 3;
Random rand = new Random();
List<String> newList = new ArrayList<>();
int count = 0;
while (count < PICK_RANDOM_STRING) {
int randomIndex = rand.nextInt(list.size());
String currentValue = list.get(randomIndex);
if (!newList.contains(currentValue)) {
newList.add(currentValue);
count++;
}
}
return newList;
}
private void removeDuplicates(List<String> list) {
try {
Log.e("One", list.get(0));
Log.e("Two", list.get(1));
Log.e("Three", list.get(2));
query1 = list.get(0); // In this vars are the strings stored with them you can then make a normal query in Firestore to get the actual document
query2 = list.get(1);
query3 = list.get(2);
} catch (Exception e) {
e.printStackTrace();
}
}
答案 3 :(得分:0)
我遇到了类似的问题(我只需要每24小时获取一个随机文档,或者当用户手动刷新页面时也可以,但是您也可以将这种解决方案应用于您的案例),对我有用的是:>
优点:
缺点
var documentId = //get document id from shared preference (will be null if not set before)
getRandomDocument(documentId)
fun getRandomDocument(documentId: String?) {
if (documentId == null) {
val query = FirebaseFirestore.getInstance()
.collection(COLLECTION_NAME)
.limit(getLimitSize())
loadDataWithQuery(query)
} else {
val docRef = FirebaseFirestore.getInstance()
.collection(COLLECTION_NAME).document(documentId)
docRef.get().addOnSuccessListener { documentSnapshot ->
val query = FirebaseFirestore.getInstance()
.collection(COLLECTION_NAME)
.startAfter(documentSnapshot)
.limit(getLimitSize())
loadDataWithQuery(query)
}.addOnFailureListener { e ->
// handle on failure
}
}
}
fun loadDataWithQuery(query: Query) {
query.get().addOnSuccessListener { queryDocumentSnapshots ->
val documents = queryDocumentSnapshots.documents
if (documents.isNotEmpty() && documents[documents.size - 1].exists()) {
//select one document from the loaded list (I selected the last document in the list)
val snapshot = documents[documents.size - 1]
var documentId = snapshot.id
//SAVE the document id in shared preferences here
//handle the random document here
} else {
//handle in case you reach to the end of the list of documents
//so we start over again as this is the first time we get a random document
//by calling getRandomDocument() with a null as a documentId
getRandomDocument(null)
}
}
}
fun getLimitSize(): Long {
val random = Random()
val listLimit = 10
return (random.nextInt(listLimit) + 1).toLong()
}
答案 4 :(得分:0)
基于@ajzbc answer,我为Unity3D编写了此代码,并为我工作。
FirebaseFirestore db;
void Start()
{
db = FirebaseFirestore.DefaultInstance;
}
public void GetRandomDocument()
{
Query query1 = db.Collection("Sports").WhereGreaterThanOrEqualTo(FieldPath.DocumentId, db.Collection("Sports").Document().Id).Limit(1);
Query query2 = db.Collection("Sports").WhereLessThan(FieldPath.DocumentId, db.Collection("Sports").Document().Id).Limit(1);
query1.GetSnapshotAsync().ContinueWithOnMainThread((querySnapshotTask1) =>
{
if(querySnapshotTask1.Result.Count > 0)
{
foreach (DocumentSnapshot documentSnapshot in querySnapshotTask1.Result.Documents)
{
Debug.Log("Random ID: "+documentSnapshot.Id);
}
} else
{
query2.GetSnapshotAsync().ContinueWithOnMainThread((querySnapshotTask2) =>
{
foreach (DocumentSnapshot documentSnapshot in querySnapshotTask2.Result.Documents)
{
Debug.Log("Random ID: " + documentSnapshot.Id);
}
});
}
});
}
答案 5 :(得分:-1)
首先,您应该手动为每个学生文档分配一个ID,这意味着您在存储文档时不应使用add()
方法。相反,请使用set()
方法:
FirebaseFirestore db = FirebaseFirestore.getInstance().
db.collection("students").document(studentId).set(studentObj);
其次,要查询10个文档,您应该使用ID生成器和for
循环分别显式调用每个文档:
for(int i = 0; i<10;i++){
int studentRandomId = (int) Math.random()*1000; // multiplied by 1000 since you have 1000 student documents
db.collection("students").document(studentRandomId).addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(DocumentSnapshot documentSnapshot, FirebaseFirestoreException e) {
randomStudentList.add(documentSnapshot.toObject(Student.class))
}
});
}
注意:您必须为学生的ID和已知范围使用连续排序的编号。