【问题标题】:About random result for query in Firestore关于 Firestore 中查询的随机结果
【发布时间】:2018-10-13 16:32:34
【问题描述】:

我在FirestoreRecycleView 中有一个数据库,可以从中获取数据。我将一些query 发送到Firestore,它会根据我的要求得到结果。但是,如果我想从应要求发给我的集合中获取 3 个随机结果。也就是说,例如,我得到 20 个结果,并且每次发送请求时只想获取 3 个结果。而且每次都必须是这20个随机的3个结果?

我发现同一问题只有一个解决方案:

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());
        }
    }
});

但这是关于如何从Firestore 中获取一些随机数据,而不是从请求的数据样本中获取。那么它有什么解决方案吗?

我的RecycleView班级:

    public class Myactivity extends AppCompatActivity {

    public RecyclerView mResultList;
    public FirebaseFirestore mFirestore;
    public com.google.firebase.firestore.Query query;
    public FirestoreRecyclerAdapter<Places, PlaceViewHolder> firestoreRecyclerAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycle_activity);
        mResultList = findViewById(R.id.list_result);

        Boolean l_check1 = getIntent().getExtras().getBoolean("1");
        Boolean l_check2 = getIntent().getExtras().getBoolean("2");
        Boolean l_check3 = getIntent().getExtras().getBoolean("3");
        mFirestore = FirebaseFirestore.getInstance();  
        if (l_check1) {
            query = mFirestore.collection("Places").whereEqualTo("colour", "1").limit(20);
            query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    List<Places> placesList = new ArrayList<>();
                    for (DocumentSnapshot document : task.getResult()) {
                        Places place = document.toObject(Places.class);
                        placesList.add(place);
                    }
                    int placeCount = placesList.size();
                    int randomNumber = new Random().nextInt(placeCount);

                    List<Places> randomPlaceList = new ArrayList<>();
                    for (int i=1; i<=3; i++) {
                        randomPlaceList.add(placesList.get(randomNumber));
                    }
                }
            }
        });
        } else if (l_check2) {
            query = mFirestore.collection("Places").whereEqualTo("colour", "2").limit(3);
        } else if (l_check3) {
            query = mFirestore.collection("Places").whereEqualTo("colour", "3").limit(3);
        }
mResultList.setLayoutManager(new LinearLayoutManager(this));
        FirestoreRecyclerOptions<Places> options = new FirestoreRecyclerOptions.Builder<Places>()
                .setQuery(query, Places.class)
                .build();
        firestoreRecyclerAdapter = new FirestoreRecyclerAdapter<Places, PlaceViewHolder>(options) {
            @Override
            protected void onBindViewHolder(PlaceViewHolder holder, int position, Places model) {

                holder.setDetails(getApplicationContext(), model.getName(), model.getImage());
            }

            @Override
            public PlaceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.list_layout, parent, false);
                return new PlaceViewHolder(view);
            }

        };
        mResultList.setAdapter(firestoreRecyclerAdapter);
    }
    @Override
    protected void onStart() {
        super.onStart();
        firestoreRecyclerAdapter.startListening();
    }
    class PlaceViewHolder extends RecyclerView.ViewHolder {

        View mView;

        public PlaceViewHolder(View itemView) {
            super(itemView);

            mView = itemView;
        }

        public void setDetails(Context context, String placeName, String placeImage) {

            final TextView place_Name = mView.findViewById(R.id.text_image_id);
            ImageView place_Image = mView.findViewById(R.id.image_id);

            place_Name.setText(placeName);
            Glide.with(context).load(placeImage).into(place_Image);

            place_Name.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(getApplicationContext(), Card_activity.class);
                    intent.putExtra("qwerty", place_Name.getText());
                    startActivity(intent);
                }
            });
        }
    }
    @Override
    protected void onStop() {
        super.onStop();
        if (firestoreRecyclerAdapter != null) {
            firestoreRecyclerAdapter.stopListening();
        }
    }
}

我从另一个activity 中提取一些Extra 并基于此结果并在if 循环中检查它,我在Firestore 中创建了一个query,然后从搜索样本中我获取3 个结果,获取“名称”和“图像”字段并将它们设置在RecycleView 中。但是如果条件相同,那么结果是一样的, 只需从 Firestore 获取前 3 个字段,按照它们在那里的放置顺序,如果它们符合条件,它们将显示在 RecycleView 中。我需要这样每次,它的 3 个结果都是随机的。

已编辑:我的 Place_class:

public class Places {
private String image, name;
public Places() { }

public Places(String image, String name) {
    this.image = image;
    this.name = name; 
}
public String getImage() { return image; }
public String getName() { return name; }   
}

【问题讨论】:

  • 降序,限3
  • 那会带来什么?毕竟每次都是同样的3条记录,除非我不添加任何新数据,是吗?@D.的
  • 希望此链接对您有所帮助:stackoverflow.com/a/58023128/1318946

标签: android firebase random android-recyclerview google-cloud-firestore


【解决方案1】:

我看到您使用了here 的确切答案,实际上是我写的。可以以非常简单的方式修改该答案以实现您想要的,但您需要使用Query。所以请添加/修改以下代码行:

Query query = studentsCollectionReference.orderBy("name").limit(20);
query.get().addOnCompleteListener(/* ... */);

然后将 for 循环更改为仅返回 3 条随机记录,如下所示:

List<Students> randomStudentList = new ArrayList<>();
for(int i = 1; i <= 3; i++) {
    randomStudentList.add(studentList.get(randomNumber));
}

【讨论】:

  • 谢谢@Alex Mamo,我理解你的逻辑,但是如何连接ArrayList 的创建并将它们从Firestore 中的所有20 条记录放入我已经使用的query?我需要将我的queryArrayList 与contidions 完全相同,例如我的whereEqualTo("color", "1")...
  • 我也不是很清楚,你的List&lt;Students&gt;,这个Student是我的模型类,有getset方法?我可以用我自己的class 使用这种方法吗?@Alex Mamo
  • 你的意思是,在我自己的query之后,以我的条件,我必须添加.addOnComleteListener()?但是我有成千上万的查询是怎么回事?我必须每次都添加它?@Alex Mamo
  • 这只是一个例子。您应该使用模型类 PlaceList 而不是 Students 类。然后使用您要使用的确切查询,并将结果添加到该 ArrayList。 “但是我有成千上万的查询”。当您查询时,这意味着您需要过滤数据。如果您有太多查询,只需将不断变化的变量传递给所需的方法(例如.whereEqualTo("colour", numberOfColor))。
  • 我编辑了我的问题,一切正常,但没有任何改变。所有 20 种变体均以相同的顺序显示。@Alex Mamo
猜你喜欢
  • 2011-03-30
  • 2021-12-05
  • 2016-05-21
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 2021-09-12
  • 1970-01-01
  • 2021-09-11
相关资源
最近更新 更多