views:

215

answers:

2

I have a question regarding how to model a many-to-many relationship in App Engine:

A Blogentry can have many tags, a tag can apply to many blog entries.

I see a couple of scenarios:

  1. Use a Set of Strings as an attribute on the blog entry.

    • This allows me to easily query for an entry using a tag
    • This does not allow me to fetch all tags and their weights (how many entries they apply to)
  2. Use an unowned relationship between an Entry and a Tag class (Set of keys for Tags in Entry class and vise versa)

    • This allows me to fetch all tags and their weights
    • This is much more comples to maintain
    • Are Set attributes lazyloaded, or would i fetch the entire graph of object every time? (Fetch an Entry, which fetches a number of Tags, each in turn fetching a number of Entries)
  3. use 1. but maintain data on tags and their weights seperately

    • This has synchronisation issues between the Tag data and the tags in the Entries

Any input and pointers would be appreciated. I think this i a quite common scenario but i haven't seen any good solutions yet.

+1  A: 

Like many other database management systems, many-to-many relationships are not natively supported in App Engine Datastore, but could be solved through a "junction table". However, since App Engine's query language does not support joins, this will be very painful to use in your application. Google's BigTable architecture in fact discourages this, because distributed joins are not efficient.

So, I suggest going with the "keep it simple stupid" rule; use the simplest thing that works. A list of strings in a "Blogentry" object sounds fairly robust. Even if it's prone to race conditions (people making updates in parallel, overwriting each other's changes), but how many people do you have editing the same blog post anyway?

intgr
HI, thanks for answering. You are right, and this is what i do now (option 1). Unfortunately, this does not allow me to easily get a list of all tags and their weights (This list is needed because i would like to have a tagcloud, and i would like autocomplete on adding tags to new entries).It seems counterintuitive, not to mention unscalable, to compute this list in-memory, but perhaps this is what needs to be done.
Wilken
A: 

I decided to go with option 3., to maintain a seperate list of tags with their weights.

This seems to work ok, although the insert/update code is a bit cluttered.

Wilken