Jeff, I agree with you that it is might not be very good to have a model mapping Community to a ListProperty of Users (since you'd get potential contention on popular communities that many people were joining at the same time and you will eventually run into the problem of having more than 5,000 users in a community). So, a model like that might not make much sense (or would just be more complex to manage when updating).
But, a model mapping User to a ListProperty of Communities should work fine (especially if you enforced the fairly reasonable rule of say.. a user cannot belong to more than 5,000 communities). Though, you only really want a model like this if it's useful to get users that belong to some set of communities. Otherwise, the plain old many to many model seems sensible since storage space is cheap and should get cheaper in the future. It seems like any alternative would end up making the coding get overly complex to manage the updating of the models.. but I can't speak from experience.. so.. On Tue, Aug 24, 2010 at 3:47 PM, Jeff Schwartz <[email protected]>wrote: > See my previous response about list properties. But yes, you could use them > but then you'd have to shard them to reduce the opportunity of contention on > updates. And the entities containing the list properties should be child > entities so that you can obtain their parent entity without having to > serialize the entities containing the list properties. There is a Google IO > YouTube video that discusses sharding and another one that discusses fanout > (membership) which is really what you are trying to implement. > > Jeff > > On Tue, Aug 24, 2010 at 3:35 PM, Eli Jones <[email protected]> wrote: > >> Here's a slight amendment to my reply.. >> >> It might make sense to express the Communities a User has joined mapping >> using a List property.. as long as you capped the communities they could >> join. >> >> Then you might be able to do more interesting queries like "Select * from >> User Where communitiesJoined = 'community1' AND communitiesJoined = >> 'community2'" etc.. to get all users in both groups in one datastore query. >> >> Also, you don't necessarily need a mapping going both ways (if you are >> using ListProperties).. you can get all users in a Community by just doing >> "Select * from User Where communitiesJoined = 'community1'" >> >> But, you'd probably want to create some test datasets (with users that >> belong to hundreds or thousands of communities) and see how the query >> performs versus the vanilla many-to-many mapping. >> >> >> On Tue, Aug 24, 2010 at 3:18 PM, Eli Jones <[email protected]> wrote: >> >>> I don't imagine storing the members of a community in a List would scale >>> very well... i'm sure the length of the list would max out pretty quick.. >>> and you wouldn't be able to query on it very well even if the list could be >>> very long. >>> >>> The second method you mention seems like it would work in a >>> straightforward manner (just having a model that maps all pairs of emailID >>> to communityID).. but that could get pretty big pretty fast.. but not sure >>> if there is any way around that (presuming you want to be able to get all >>> users in a community or all communities for a user). >>> >>> Though, you can't do neater queries on that model for things like all >>> users that are in community1 and in community2.. or all communities that >>> have user1 and user2 in them without doing it in memory. >>> >>> But, that wouldn't matter if you don't care about that.. or if you do >>> care about that, you could create a separate model for looking at that sort >>> of information. >>> >>> >>> On Mon, Aug 23, 2010 at 1:03 PM, skin <[email protected]> wrote: >>> >>>> Hi, >>>> >>>> I am trying to understand the way to create a many to many >>>> relationship in datastore. Let me take an example to start with. >>>> >>>> Suppose I have users and communities as two entities. A user can join >>>> as many communities as he wants and a community can have a lot of >>>> users. >>>> >>>> ------------------ ------------------------- >>>> | | | | >>>> | USER | m --- n | COMMUNITY | >>>> | | | | >>>> ------------------ ------------------------- >>>> First way of doing it >>>> ------------------------------- >>>> class User { >>>> String emailID // primary key for user >>>> List<Key> communitiesJoined >>>> ...... >>>> } >>>> >>>> class Community { >>>> Key communityID // primary key for community >>>> List<String> usersInCommunity >>>> >>>> } >>>> >>>> User Joins community --- >>>> user.communitiesJoined.add(coummunityiD) >>>> && >>>> community.usersInCommunity.add(userID) >>>> >>>> Get Communities Joined By User -- >>>> user.communitiesJoined >>>> >>>> Get Users in a community -- >>>> community.usersInCommnity >>>> >>>> >>>> Second way >>>> --------------------- >>>> class User { >>>> String emailID // primary key for user >>>> } >>>> >>>> class Community { >>>> Key communityID // primay key for community >>>> } >>>> >>>> class UserCommunityMapping { >>>> String emailID >>>> Key communityID >>>> } >>>> >>>> User Joins community --- >>>> UserCommunityMapping ucm = new UserCommunityMapping() >>>> ucm.emailID = user.emailID >>>> ucm.communityID = community.communityID >>>> >>>> Get Communities Joined By User -- >>>> select emailID from UserCommunityMapping where communityID = >>>> coummunity.communityID >>>> >>>> Get Users in a community -- >>>> select coummunityID from UserCommunityMapping where emailID = >>>> user.userID >>>> >>>> Now, can somebody tell me which is the better way to do it in >>>> appstore? Below are the categories. >>>> >>>> Performance during query? >>>> Memory utilization? >>>> Easy way to query? >>>> >>>> If there is any other way, you can share that as well. >>>> >>>> Thanks in advance. >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Google App Engine" group. >>>> To post to this group, send email to [email protected]. >>>> To unsubscribe from this group, send email to >>>> [email protected]<google-appengine%[email protected]> >>>> . >>>> For more options, visit this group at >>>> http://groups.google.com/group/google-appengine?hl=en. >>>> >>>> >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "Google App Engine" group. >> To post to this group, send email to [email protected]. >> To unsubscribe from this group, send email to >> [email protected]<google-appengine%[email protected]> >> . >> For more options, visit this group at >> http://groups.google.com/group/google-appengine?hl=en. >> > > > > -- > -- > Jeff > > -- > You received this message because you are subscribed to the Google Groups > "Google App Engine" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]<google-appengine%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/google-appengine?hl=en. > -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.
