Reputation: 169
As far as I can tell, the only reason you might use an array of pointers is to preserve ordering, as a PFRelation instance does not support ordering. Otherwise, they appear to behave identically, albeit PFRelation is more scalable and also has a nifty built-in 'query' method to restrict a query just to the objects in the PFRelation instance, which is super helpful sometimes.
PFRelation *relation = ...
PFQuery *query = [relation query];
Context: I am building an app in which each PFUser instance HAS MANY TennisGame instances (could be a large number), and the TennisGame instances HAS MANY PFUser instances (either 2 or 4, depending on whether it was a singles game or a doubles game).
Question: What is the best way to organise my data on parse.com ? I was considering a PFRelation in my PFUser class (to TennisGame instances), as well as an array or 2 or 4 pointers in my TennisGame class (to PFUser instances). But do I need both? If not, which is best?
Upvotes: 3
Views: 2003
Reputation: 2768
knshn's answer is not good because it's making the assumption that PFRelation
must be used anytime the "MANY" side has more than 100 relationships due to performance issues.
This is not true, because you can create a one-to-many relationship with "Pointer relations" and Parse can handle more than 100 relationships no problem. Or it can even effectively handle a many-to-many relationship with "Array relations" when one side has more than 100 relationships and the other one less than 100. So the correct answer should have mentioned that having more than 100 relationships becomes an issue ONLY when using "Array relations", ie. making an array with more than 100 items and setting it to an object.
So going back to the original question, I would suggest you to have an array of PFUser
players in the TennisGame
instance, because each game will have only 2 or 4 players at a time, or at least definitely less than 100.
Therefore, if you want to get the PFUser
players from a specific TennisGame
instance, you would have to perform a query like this:
PFQuery *query = [PFQuery queryWithClassName:@"TennisGame"];
[query includeKey:@"players"];
[query getObjectInBackgroundWithId:tennisGameId block:^(PFObject *tennisGame, NSError *error) {
if (tennisGame) {
tennisGame[@"players"];
}
}];
Next, if you want to get all the games played by your current user, sorted by date, you can perform the following query:
PFQuery *query = [PFQuery queryWithClassName:@"TennisGame"];
[query addDescendingOrder:@"createdAt"];
[query whereKey:@"players" equalTo:[PFUser currentUser]];
[query findObjectsInBackgroundWithBlock:^(NSArray *tennisGames, NSError *error) {
// do whatever you need with the results
}];
And finally, you may ask, "Wait! wouldn't be a performance issue if a player has played more than 100 games?" And the answer is no, because thats an issue for arrays only and not for queries. It would be an issue if the games were saved in the PFUser
instance as an array, instead of the players array being saved in the TennisGame
instance. Also, PFRelation
is some kind of query as well, so its the recommended way to retrieve large amounts of objects.
BONUS: When to use PFRelation
?
It's ideal when you need a A-LOT-to-A-LOT relationships, so using PFRelation
for something like "followers" on a social network app makes sense, because each account can have more than 100 "followers", and each account can be a "follower" to more than 100 other accounts.
Upvotes: 0
Reputation: 3461
The question is about how you access your data. For your case, you can think about these questions:
include
on queries. You can't do include
with relations and you need to do one more query to access a user's TennisGames.I suggest you to watch this video about Parse relationships from Parse developer days.
Moreover, you don't need the keep the relationship in both sides. This would make it more complicated to create and update them.
Upvotes: 10