Hi James, Thanks for your response. You are right, the Pattern is quite common, if not ubiquous in all systems.
My particular question is related with Voyage+MongoDB, and also could apply to Magritte (given the fact Voyage "inherits" its descriptions model). I sucessfully implemented this pattern with ORMs using an intermediary table for the relation, or even reifying the relation as a first class object. I also used the #select: technique to avoid duplication of "responsibility" and caching at one side of the relation. But I always did it "in memory" with no mapping et all, just plain old smalltalk objects (POSO?) and using ORM solutions. What I need to know now is: 1) How to do this with voyage+MongoDB 2) I want to have a two way relation, it is both members and groups have a collection (members know their groups and viceversa). This requires additional maintenance, but with a higher performance, and doesn't require me to load all groups if I'm just materializing one member. Regards! Esteban A. Maringolo 2013/8/30 James Foster <smallt...@jgfoster.net>: > Hi Esteban, > > What you have described is quite common and there are a variety of ways of > designing this sort of object model. If you were dealing with a relational > database, then you would have a Group table, a Member table, and a Membership > table. The Membership table would have one row for each member/group pair and > the member ID and group ID would be the primary columns (perhaps with other > things like date joined, date expired, etc.). With an index on the member ID > and group ID, one could quickly find all the groups for a member and all the > members for a group, and each piece of data would exist in only one place > ("normalized"). One could take a similar approach with objects, having three > collections containing Groups, Members, and Memberships respectively. You > could have an accessor in Group that returned members based on a select from > the Memberships collection and an accessor in Member that returned groups > based on a select from the Memberships collection. > > Alternatively, if you wanted to avoid the #'select:' call in one or both > lookups, you can cache the respective subcollections in Group and/or Member > and drop the Memberships collection. If you cache in only one place (e.g., > each Group has a collection of Members), then you can add a method in Member > that does a #'select:' of Groups where a Group has the Member. If you cache > in both places then your getters/setters in each can update the other (with > the understanding that you are duplicating data to get performance > efficiency). > > Again, this problem is very common. Consider students in classes, persons > with addresses, persons with hobbies, etc. Your choices are basically (1) > three collections, no duplicates, select for both queries; (2) two > collections, no duplicates, cache for one query, select for the other query; > and (3) two collections, caches for each query. Which is preferable depends > on your typical sizes and lookup patterns. If performance is not an issue, > then start with whatever is simplest for you to code. I lean toward the three > collections with the lookup penalty (GemStone's ability to index collections > makes this approach very efficient), but if most of your lookups are from one > side or the other and scanning the full collection is slow, then cache in one > or both places. > > If you have a composite, the analysis is similar since Smalltalk does not > require static typing of variables. You just need to take care that your > accessors can give back the expected objects. > > James > > On Aug 29, 2013, at 6:12 PM, Esteban A. Maringolo <emaring...@gmail.com> > wrote: > >> Hi all, >> >> Let's say I have a class Group and a class Member. >> >> aGroup has many members. >> and aMember can belong to many groups. >> >> What is the "proper" voyageDescription for those one to many relations? >> >> Should I do something extra? >> >> Everytime I add a member to the group, both the member and the group >> get their references updated. >> Now when I add a member to a group and save it, I also save the >> member. Is there another way to avoid this? >> >> Any recommended practice for this? >> >> Next level question: What if it gets composite? it is... a Group has >> other Groups as members :) >> >> >> Regards! >> >> Esteban A. Maringolo >> >> > >