Search code examples
androidsqlrealmrealm-migrationrealm-list

Android: using Realm to make a nested query?


I have a list of Teachers that each contain a list of Student objects. Each Student contains a list of schoolbooks that he has to bring each day. It looks like this:

Teacher { 
String teacherName;
RealmList<Student> students = new RealmList<>(); 
}

Student { 
String studentName;
RealmList<SchoolDay> schooldays = new RealmList<>(); 
}

SchoolDay { 
String day;
RealmList<RealmString> schoolbooks; 
}

(RealmString is simply primitive String wrapped as a RealmObject)

I want to extract the list of schoolbooks for a certain student on a certain day - several students might have the same schoolbooks, but I'm only interested in the books for one particular student on one particular day (for example, Sunday). A student might be in the classes of several teachers, but I'm only interested in the result for one of them as the weekly booklist will be different for each one. Sample query data might be:

teacher : steven

student : austin

day     : sunday

This is where I get stuck - how do I subquery this? To get the teacher that I'm interested in:

RealmResults<Teacher> = realm.where(Teacher.class).equalTo("teacherName",  "steven").findAll();

However, I then have to run a subquery on the teacher and a subquery on the student - or better yet, run all of them in the same query somehow. What I want to get as my final result is just the string representing the schoolbooks for that one particular student. How can I do this?


Solution

  • Can you try like that :

    realm.where(Teacher.class)
    .equalTo("teacherName",teachername)
    .equalTo("students.studentName",studentname)
    .equalTo("students.schooldays.day",day).findAll();
    

    After all you have Teacher object(s) and you can get variables in one query :

    RealmResults<Teacher> teachers= your query above;
        for(Teacher teacher:teachers){
           //remember still you can have multiple students for given teacher
           for(Student student:teacher.getStudents()){
               for(Schoolday schoolday:student.getSchooldays()){
                 schoolday.schoolbooks bla bla bla...
               }
           }
        }
    

    Why we using for loop : because findAll() method can return multiple results, if you want single Teacher object use findFirst()

    This will return you Teachers of given teachername attribute that contains/includes students with given student name : studentname and those students have schooldays with given: day name.

    I think the last explaination is quite a bit hard to understand, now I explain it with examples:

    1. In first query you are getting Teachers with name= "Yasin". Assume that after this query you got 5 Teachers with name "Yasin".
    2. Then in second query you are searching this 5 Yasin teachers; if their one of students name is "Jon". Assume that you have 3 Yasin teachers after that query.
    3. Then in the last query you searching of that 3 "Yasin" teachers; if their one of students school day is "Sunday".

    You can take a look at this question : how-to-make-a-nested-query-in-realm

    Also this question is good for referencing ; it was helpful for me: realm-android-nested-query