views:

119

answers:

1

I'm trying my hand at google appengine and using the datastore with php and quercus. I'm not familiar with Java or Python, so lots of learning going on here. I've got pages rendering, and i'm able to get data in and out of the datastore.

The app I am building has users, groups, topics and comments. A group has users, and users can belong to multiple groups. When a user logs in, I display the groups they are members of, and the topics of those groups.

I've got this currently built in MySql, and am now figuring out how to get it into appengine.

The way I see it, a group is a parent which has topics and users as children. Topics have comments as children.

However, I have to get the groups that a user belongs to when the user logs in. Therefore, I was thinking of a separate parent entity which stores the user, contact and login info, and that user would have children containing the group id which each user belongs to, so that I know what groups to fetch.

The users are children of the group so that I can display all the users of a group, but maybe there is a more efficient way to do it.

Like this

Groups(EntityGroup) - GroupName, Owner
↳ Topics - TopicName, Content, Owner
       ↳ Comments - Comment, Owner
↳ Users - userid

Users(EntityGroup) - userName, email, password
↳ userGroup - groupid

Then, when a user logs in, the logic looks like this

SELECT groupid FROM Users where password=hashofpassword+uniqueusername
foreach(groupid as group){
   SELECT users from group;
   SELECT topics from group
   foreach(topicid as topic){
     SELECT comments;
    } 
}

The reason I'm looking at it like this is because when a user logs in, I can't very well go looking through each group for the user, and I only would want to store the login info in one place.

Please don't recommend me to the code.google.com documentation, as I've gone through that many times already, but am not completely understanding what's going on with appengine.

also, is the way I've outlined above the proper way to visualize the datastore? I think visualizing the data has been a struggle which might be causing some of the challenges.

+1  A: 

It looks to me like there is a many-to-many relationship between Users and Groups, yes? A user can belong to many groups, and a Group can have many users who are subscribed to it. The most logical way to represent this is AppEngine to is to give the User entity a ListProperty that holds the Key of the eahc of the groups to which he belongs. In Python, it would look like this:

class User(db.Model):
    userName = db.StringProperty()
    email = db.EmailProperty()
    password = db.StringProperty() 
    groups = ListProperty(db.Key)

Whenever the User subscribes to the group, you add the Group's key to the groups list.

Likewise, the Group entity will have a ListProperty that contains the Keys of each User who belongs to it.

You wouldn't want to make the Users children of the Group, as that would make it very difficult or impossible for a User to belong to more than one Group.

The difficulty that you will have is that when a User joins a group, you will need to update the Group in a Transaction -- you can only have one User being added to a Group at a time; otherwise, you have the possibility that one write will overwrite another. Presumably, the User can be updated outside of a transaction, as he or she should only be joining one group at a time.

Adam Crossland
Thank you Adam, that confirms my thinking. I shouldn't have to worry about a user being added to many groups at one time. I wasn't thinking 'list property' for the User entity or for the group, though I've seen that a few times now. I was thinking a child for each group the user belongs to, but I'll take a closer look at ListProperty, as that sounds like the way to go. Thanks for your very thorough response.
pedalpete