I need to do a simple query sort with Parse.
I have two classes: Captain
and Boat
. Every Captain
has a Boat
point
It would be nice if you could use dot notation on the sort qualifiers, like:
[captainQuery orderByAscending:@"boat.name"];
Unfortunately the attribute dot notation applies only to includeKey:. So the way to do this to fetch, including the related object, then sort locally using the attribute of the related objects:
// ...
[captainQuery includeKey:@"boat"];
[query findObjectsInBackgroundWithBlock:^(NSArray *captains, NSError *error) {
NSArray *sortedCaptains = [captains sortedArrayUsingComparator: ^(PFObject *capA, PFObject *capB) {
return [capA[@"boat"][@"name"] compare:capB[@"boat"][@"name"]];
// or reverse param order for descending
}];
}];
EDIT - @Logan helpfully points out that this answer doesn't scale well if your query pages through thousands of captains. If the captain count is huge, it might be better to include a boat->captain pointer and do the following:
More roundabout-ly, you could fetch boats, orderByAscending on their name, includeKey their captains (if your boats have a back-pointer to captain), and then map over the returned (sorted) boats for their captains.
You can use relation query for multiple queries, the query code should looks like below:
PFObject *captain = [PFObject objectWithClassName:@"Captain"];
PFRelation *relation = [captain relationForKey:@"Boat"];
PFQuery *relQuery = [relation query];
[relQuery orderByDescending:@"name"];
// Add other query constraints
[relQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
// There was an error
} else {
// All the captains sorted by related boat's names
}
}];
There are some useful links below:
http://blog.parse.com/2012/05/17/new-many-to-many/ https://parse.com/docs/ios_guide#objects-pointers/iOS
There is a scalable solution for this, with rather minimal overhead: Currently you have a table of boats and a table of captains, where each captain contains a pointer to a boat.
You should add a third table - let'c call it 'captains boats', which contains all the boats that are contained in a captain object. You maintain it by adding the boat when a new captain is added and by removing it from the table when a captain is deleted.
In order to sort the captains by their boats:
Query 'Captains', use the 'containedIn' method with the boat list from step 1: [captainQuery whereKey:"boat" containedIn:boatList]
.
Now you have only the captain objects you need (out of a possible million). Sort them locally according to whatever.