How to perform Parse query using relation where relation contains one or no objects matching conditions?

943 views Asked by At

I'm using the Parse iOS SDK in Objective-C and trying to query for objects based on whether an object's relation contains either at least one object matching a particular query or has no relational objects matching that same query. I'm trying to use -[PFQuery whereKey:matchesQuery:] and -[PFQuery whereKey:doesNotMatchQuery:] to do this but I'm getting the error "bad type for $inQuery" and believe that this is related to what I'm trying to do. Is there a way to be able to query for such objects in a single PFQuery? If not, what is the best way of accomplishing this?

I found the following existing answer from the old Parse forums that uses -[PFQuery whereKey:containedIn:], but it appears to use an array of PFObjects rather than a PFRelation for its key and also requires an existing array of objects to match against (and therefore didn't appear to work for me): https://www.parse.com/questions/query-where-relation-contains-any-object-from-array

Example:

Let's say that I have two classes of PFObjects: Teacher and Student. A Teacher has a to-many PFRelation students to Student, while each Student has properties firstName and lastName, each of which take a string. I want to be able to query for Teachers based on properties of their Students, e.g.:

  • All teachers that have at least one student named Billy.
  • All teachers that have no students named `Emily'.

To do this I am currently using the following code to search for teachers with at least one student named "Billy":

PFQuery *teacherQuery = [[PFQuery alloc] initWithClassName:@"Teacher"];
PFQuery *studentsQuery = [[PFQuery alloc] initWithClassName:@"Student"];
[studentsQuery whereKey:@"firstName" equalTo:@"Billy"];
[teacherQuery whereKey:@"students" matchesQuery:studentsQuery];

and the following code to search for teachers with no students named "Emily":

PFQuery *teacherQuery = [[PFQuery alloc] initWithClassName:@"Teacher"];
PFQuery *studentsQuery = [[PFQuery alloc] initWithClassName:@"Student"];
[studentsQuery whereKey:@"firstName" notEqualTo:@"Emily"];
[teacherQuery whereKey:@"students" matchesQuery:studentsQuery];
1

There are 1 answers

1
Raesu On

You can actually query the PFRelation itself. I imagine it would be something like:

PFObject *teacher = ...// teacher object you got from query
PFRelation *students = [teacher relationForKey:@"students"];
[students whereKey:@"first_name" equalTo:@"Billy"];

Not easy for me to test myself right now but maybe you could use that as a subquery? I would be interested to know if you ever solved this.