0

PROBLEM

I want to get 5 random nodes in firebase in which the value "STATE" is equal to "ACEPTED", both solutions i have implemented take a lot of time

SOLUTION 1:

This solution consist of getting random values and if they "STATE" equals to "ACEPTED" add it to my list.

private DatabaseReference mdatabas;
private List<String> keys;     

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_makequestions);

    keys=new ArrayList<>();

    mdatabas=FirebaseDatabase.getInstance().getReference()
    .child("QUESTIONS").child("SPANISH");

    getNofQuestions();
}

private void getNofQuestions(){
    mdatabas.child("QUESTIONID").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            //QUESTION ID IS EQUAL TO THE NUMBER OF QUESTIONS
            nOfQuestions=dataSnapshot.getValue(Integer.class);
            getRandom();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

private void getRandom(){
    getQuestion(random.nextInt(nOfQuestions-11)+11);
}

private void getQuestion(int random){
    mdatabas.child(String.valueOf(random)).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if(keys.size()==4){
                Toast.makeText(getApplicationContext(),"FINISHED",Toast.LENGTH_SHORT).show();
            }
            else{

            if(dataSnapshot.child("STATE").getValue(String.class)!=null){
                if(dataSnapshot.child("STATE").getValue(String.class).equals("ACEPTED")){
                    keys.add(dataSnapshot.getKey());
                    getRandom();
                }
                else{
                    getRandom();
                }
            }
                else{
                getRandom();
            }

            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

}

SOLUTION 2 Basically i get all the questions that their state value is equal to accepted, shuffle them, and make a sublist.

private void getQuestions(){

    mdatabas.orderByChild("STATE").equalTo("ACEPTED").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot snapshot:dataSnapshot.getChildren()){
                keys.add(snapshot.child("ID").getValue(String.class));
            }
            Collections.shuffle(keys);
            List<String> finalKeys = keys.subList(0, 4);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

}

}

Json structure(It is below QUESTIONS/SPANISH)

{
 "0" : {
"ID" : "0",
"MISPELLED" : 1,
"SPAM" : 1,
"STATE" : "ACEPTED",
"WRONGLANGUAGE" : 1,
"WRONGREGION" : 1
},
"1" : {
"ID" : "1",
"OPTION1" : "Elementos químicos ",
"OPTION2" : "Huesos ",
"OPTION3" : "Órganos ",
"OPTION4" : "Células ",
"QUESTION" : "La estequiologia se encarga de estudiar "
},
"2" : {
"CORRECT" : 1,
"ID" : "11",
"LIKES" : 15,
"OPTION1" : "Elementos químicos ",
"OPTION2" : "Huesos ",
"OPTION3" : "Órganos ",
"OPTION4" : "Células ",
"QUESTION" : "La estequiologia se encarga de estudiar ",
"STATE" : "ACEPTED",
"WRONG" : 1
},
"3" : {
"CORRECT" : 2,
"ID" : "12",
"LIKES" : 6,
"MISPELLED" : 2,
"OPTION1" : "Ingestión de cecaria enquistada en \r\nplanta de agua dulce.\r\n ",
"OPTION2" : "Ingestión de metacecaria enquistada en \r\nplanta de agua dulce.\r\n",
"OPTION3" : "Ingestión de metacecaria enquistada en \r\nplanta de agua salada",
"OPTION4" : "Ingestión de esporocito enquistada en \r\nplanta de agua dulce.\r\n",
"QUESTION" : "Mecanismos de transmisión de faciolopsis buski ",
"WRONG" : 3
},
 "QUESTIONID" : 3
}

So i my question is if there is some another way of getting the data or any improvements that i can make to mines to reduce time complexity?

Martin De Simone
  • 2,108
  • 3
  • 16
  • 30

1 Answers1

0

As is common in many NoSQL databases, model the data for the use-case you have. Since you are looking to get a random question that has been accepted, keep a list of the minimal information needed for that.

acceptedQuestionIds
  <questionId>: true

With that structure you can load the list of accepted question IDs and pick one at random, which should be a lot faster.

Some comments:

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807