I think you misunderstand what I proposed

Class UserActivity {
Key id;
Key activityId; // id of activity class
Key userId; // id of User class whom this user activity belongs to
--- vvv ADD THIS vvv ---
List<Key> friendIds; // list of all of userId's friends
}

When you create an update to your status "Hurray I got some solution",
you wil create one row for class user activity where your status will
be saved (and that row will have a list of all your friend ids in it).
That's it.. stop adding 500 rows, you don't need them. (you need to
put a list of all of your friends into every activity you create)

When your friends look at their wall, you just query UserActivity
where friendIds = friendId. (list query returns true if one of the
items in the list equals friendId). This will give them your update
because they are contained in friendIds list of that user activity.

Another way of saying this. Stop looking at it from perspective of
distributing the information all over the place when you create it.
Instead, via friendIds list, you are marking that activity with the
people who have access, and then when they ask for their "wall", they
say "give me all activities I have access to arranged by date".

On May 19, 9:42 am, Ravi <ping2r...@gmail.com> wrote:
> Thanks Tristan
> I like the idea of UserRegistrar class, may be i will use this to keep
> the Friend relation.
>
> But still worried about UserActivity as GAE doesn't support more then
> 30 parameters in contains query. So i will be able to query
> UserActivity only for 30 users at one time(then run remaining in the
> batch of 30 each) and then i will need to sort them in memory for
> latest activities and it will not be scalable solution.So as Baz said
> need to look into write once kind of solution. And make sure data is
> not being duplicated a lot but i will just keep ids in every user's
> activity table.
> So something liek this
> class Acitivty
> {
> Key id;
> String status;
> ....
>
> }
>
> Class UserAcitivity{
> Key id;
> Key actitityId; //Id of Activity Class
> Key userId; //Id of User Classm whome this UserActivity belongs
> boolean myUpdate;//it will distinguish if this activity is mine or my
> friends/some group etc
>
> }
>
> So basically if i want to update my status as "Hurray i got some
> solution". Then i will create one row for class Activity where my
> status will be saved.
> Then i will create one row in UserActitvity where my userId,just
> created activityId and myUpdate=true.
> And say i have 500 Friends, then i will create 500 more rows with
> userId as my friend's id, activityId as what i created above and
> myUpdate as false;(And i hope i will be able to finish it before Big
> Daddy DeadlineExceedException comes to me :) )
>
> So when i want to see all updates including mine and friend's on my
> wall, then i will query this table(UserActivity) with userId=myId
> order by updationDate and according to my web page i may be interested
> in top 30 or 50 or 100 results only and then for that i can lookup
> Activity table to get exact data.
> And if retrieval of data from Activity class is pain, then i may merge
> it with the userActivity and duplicate the data like activityStaus in
> 500 rows(just to make retrieval faster).
>
> Feel free to comment on this design.
>
> (There is always a better solution)
> Thanks,
> Ravi.
>
> On May 19, 1:13 am, Tristan <tristan.slomin...@gmail.com> wrote:
>
>
>
> > What about doing this?
>
> > Have your user activity object keep track of friends as well... So
> > something like
>
> > Class UserActivity
> > {
> > Key id;
> > String statusMessage;
> > Date time;
> > User user;
> > List<Key> friends
>
> > }
>
> > Then when you want to display the "wall", you just query all User
> > Activity objects that have your user in it. (for one, I would not user
> > List<Key> because you have a potential of running out of space, ie >
> > 1MB and then you start getting errors, but it's a design decision).
> > But the above saves you a lot of time... because when User Activity is
> > generated by user1 (who is friends with user2), you just copy the
> > user1's friend list into it while you're creating it, so just 1 write
> > operation. Then if you're user2 and want to see your wall, just run a
> > query against User Activity where friends = user2Key. 1 query
> > operation.
>
> > As far as how to be friends of friends, instead of storing the
> > relationship in your User object, have something like UserRegistrar
> > that is essentially this:
>
> > UserRegistrar {
> > List<Key> users
>
> > }
>
> > Most of the time you will just have 2 users in that list, but what
> > that buys you is being able to do 1 write and document relationship
> > going both ways. Then if you want to find friends of user2, you just
> > query UserRegistrar where friends = user2. When you have all those,
> > combine the list and every user listed (except listing of user2) is a
> > friend of user2. So again, 1 query operation.
>
> > On May 18, 1:47 pm, Baz <b...@thinkloop.com> wrote:
>
> > > I think you're best bet is to do all the work in the write, and have each
> > > profile's page constantly updated and ready for an extremely simple read.
> > > For one, this will significantly reduce your costs, because everyone reads
> > > more than they write. Two, by the time you get big enough to surpass the 
> > > 30
> > > second limit, you will probably be able to use "Background servers capable
> > > of running for longer than 30s" 
> > > (http://code.google.com/appengine/docs/roadmap.html)
>
> > > Cheers,
> > > Baz
>
> > > On Tue, May 18, 2010 at 8:43 AM, Ravi <ping2r...@gmail.com> wrote:
> > > > Thanks Li for looking into it.
> > > > For me 1-2 minute delay is fine, problem is like contains query(for
> > > > finding friend's data), i can pass max 30 user id, so basically on one
> > > > page i will be able to show max 30.
> > > > But in other case where wall type data need to be saved queries need
> > > > to perform faster and need to break the limit of 30 as i would like to
> > > > get latest activity from all of my friends rather then first 30
> > > > friends. So if i have 300 friends i may need to run such query 10
> > > > times in the batch of 30 nad each time need to go through activties
> > > > and sort them out which will be very time consuming and sure user will
> > > > not like the response time.
> > > > I am thinking why not do it at the write time that my updates goes to
> > > > all of friend's domain but again in one 30 second request i will try
> > > > to create/update my domain(user Data) + 300(assuming i have 300
> > > > friends) other domains. I am not sure how it will perform.
>
> > > > But i would love to see some solution where write is less and still
> > > > read is faster like any other site(facebook/twitter etc)
>
> > > > Ravi.
>
> > > > On May 18, 4:31 pm, Yiming Li <yiming...@umail.ucsb.edu> wrote:
> > > > > This is an interesting problem, I am not an expert on database design,
> > > > > especially key-value based datastore,  but I will try to answer this
> > > > > question.
>
> > > > > For me, the design like
> > > > > Class User{
> > > > > Key id;
> > > > > String name;
> > > > > String email;
> > > > > List<key> friends.
> > > > > ...etc}
>
> > > > > makes perfect sense, and as you said, you can do more query on
> > > > > something like "UserActivity" or "TimeBecomeFriends", with
> > > > > "user1Id=<userId> or user2Id=<userId>". approach. I am also fine with
> > > > > it.
>
> > > > > How big is your application? I think a good design is relevant to the
> > > > > scalability, and we are always trading storage space with query time.
>
> > > > > Another thing maybe useful is memcache, using it may lead to a gain in
> > > > > performance, although it may bring a bit data inconsistency,  however
> > > > > I think it's ok. For example, it should be fine if you see your
> > > > > friends' latest post 1 minute later.
>
> > > > > Maybe there is some paper talking about datastore design for scalable
> > > > > applications? Not sure.
>
> > > > > Thanks
>
> > > > > On Tue, May 18, 2010 at 7:58 AM, Ravi <ping2r...@gmail.com> wrote:
> > > > > > Hi,
> > > > > > I am trying to design a website like Facebook, where user will have
> > > > > > friends and will have wall where they can see there friend's updates
> > > > > > etc. While designing it on GAE i got confused with what will be the
> > > > > > best approach like data duplicate, data read time or data write time
> > > > > > etc
>
> > > > > > Friend's Design:
> > > > > > I thought there will be User and User will be friend with another
> > > > > > User.
>
> > > > > > Class User{
> > > > > > Key id;
> > > > > > String name;
> > > > > > String email;
> > > > > > ...etc
> > > > > > }
>
> > > > > > Now i definitely can not have owened relatioship with Friends means 
> > > > > > I
> > > > > > can not have List<User> friends in my User Class as it will not be
> > > > > > same domain(User) data, so i thought ok i will have List<Key> or
> > > > > > List<Long> User Ids as Friends
> > > > > > Class User{
> > > > > > Key id;
> > > > > > String name;
> > > > > > String email;
> > > > > > List<key> friends.
> > > > > > ...etc
> > > > > > }
> > > > > > And confusion/problem begins.
> > > > > > First a Friendship is supposed to be from both side, so it should be
> > > > > > defined only once but in this design both Friends will have each
> > > > > > other's id in there friend list. Basically its not a typical
> > > > > > relationship. What if i want to keep friendship info like when it
> > > > > > started, who introduced etc. Then i may need to create a new Friend
> > > > > > class with two fields as user1Id and user2Id and query this class 
> > > > > > with
> > > > > > user1Id=<userId> or user2Id=<userId>. But not sure about this
> > > > > > approach.
> > > > > > Second i am doing data duplicate(but i am fine with it if it can be
> > > > > > proved as best solution).
> > > > > > Third: I am showing one user's profile and want to show his friends 
> > > > > > on
> > > > > > one page, so first i need to get the User and its Friend List<Key>
> > > > > > then i need to search User for each and every Id to get each user's
> > > > > > data(like name.profile id and photo). For me it seemed bit longer
> > > > > > process.Not sure how queries will perform.
> > > > > >  Pseudo Code will be like this
> > > > > >   > Get Logged In User
> > > > > >   > Loop through friends field
> > > > > >        >Begin
> > > > > >          get User for each iterated Friend Id.
> > > > > > //and if we want to show how many friends that user have, then i 
> > > > > > will
> > > > > > be accessing friend list for each friend,so there will be lot of 
> > > > > > data
> > > > > > read from database.
> > > > > >        >End
> > > > > > put all data in jsp to compile and show it to user.
>
> > > > > > Other design problem related to wall like Facebook wall/profile,
> > > > > > Lets say i have UserActivity class to keep track of User's Activity
> > > > > > and that can be owned by User, so User class can look like
> > > > > > Class User
> > > > > > {
> > > > > > Key id;
> > > > > > String name;
> > > > > > String email;
> > > > > > List<Key> friends//assume we are going with this kind of design
> > > > > > List<UserActivity> activities
> > > > > > }
>
> > > > > > Class UserActivity
> > > > > > {
> > > > > > Key id;
> > > > > > String statusMessage;
> > > > > > Date time;
> > > > > > User user;
> > > > > > }
>
> ...
>
> read more »

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine for Java" group.
To post to this group, send email to google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.

Reply via email to