Cool, if you structure your entity class like this though:

    class Entity {
         List<String> tags;
         String foo;
     }

how are you going to query which Entity instances match a given tag? I think
that all the tags need to be indexed so your query statement can find them -
I'm not 100% sure on this, if you can somehow match on that List<String>,
that would be new to me! I was thinking you might have to decide how many
tags an Entity can have, and explicitly declare each like:

    class Entity {
         String tag1, tag2, tag3;
         String foo;
     }

only the first tag is required, the other two can be null. Then your query
statement would have to be something like:

    select from Entity where tag1 == 'cow' || tag2 == 'cow' || tag3 ==
'cow';

not sure if there's a better way to do it, let us know what you try because
this is probably a pattern that can be reused for others wanting to do the
same thing,

Thanks,
Mark


On Wed, Jul 21, 2010 at 3:15 PM, planetjones <[email protected]> wrote:

> Mark,
>
> Thanks very much for this - it's useful.  I'm slowly getting used to
> this non-relational way of thinking.
>
> The count of the tags doesn't need to be 100% accurate, as it will
> only be used to approximate how many entries exist for a given tag -
> the tag cloud aim is to show tags associated with many entities in a
> larger font and tags associated with fewer entities in a smaller
> font.  If the insert, update or delete of Entity succeeds and gets
> committed, but the persistence action against the TagCounter fails in
> a few instances that would not be a big deal.
>
> I'll probably allow three tags per Entity, so was planning on:
>
>  class Entity {
>          List<String> tags;
>          String foo;
>      }
>
> for flexibility in of the number of tags.
>
> So when inserting a new entity I would need to:
>
> Create Entity
> For each tag in Entity select TagCounter
> If tag counter exists for tag increment count by 1
> If tag counter does not exist for tag create TagCounter with count of
> 1
>
> When deleting an entity I would need to:
>
> For each tag in Entity select TagCounter
> Decrease count by 1 of TagCounter
> Delete Entity
>
> This sounds ok to me.  When a user clicks a tag the query is simple
> too.
>
> I'll give this a try and see how it looks.
>
> Thanks again.
>
> On Jul 21, 12:46 pm, Mark <[email protected]> wrote:
> > I probably have a naive understanding of what you're doing, maybe
> > explain a little more, but to me it looks like this:
> >
> >     class TagCounter {
> >         int count;
> >         String label; // primary key, unique tag name.
> >     }
> >
> >     class Entity {
> >         String tag;
> >         String foo;
> >     }
> >
> > whenever the user creates a new entity, record its tag(s), then
> > increment the appropriate TagCounter instance. Keeping counters like
> > this introduces a bottleneck and goes against what you want to be
> > doing for a highly scalable web service, so you may want to shard them
> > (imagine you have thousands of users all trying to increment a single
> > tag counter at once).   Since the above two classes won't be in the
> > same entity group, you wouldn't be able to perform both operations in
> > a single transaction. You can either accept the fact that your tag
> > count may be out of sync with the actual number of entities with that
> > tag, or you can have a multistep process and clean up dangling tag
> > counts with a task (eventual consistency might be the term here). I'm
> > referring to Nick Johnson's article on distributed transactions which
> > I think you can modify to do what you're looking for:
> >
> >    http://blog.notdot.net/2009/9/Distributed-Transactions-on-App-Engine
> >
> > I'm still learning app engine so take the above with a big grain of
> > salt. To me, it seems that if you want to write a highly scalable web
> > service, you need to accept that you may lose some data precision, or
> > you have to put in additional work to get what you want (compared to
> > assuming a single mysql instance etc).
> >
> > Anyway, after you implement something like the above, your original
> > two queries should be easy to do. You probably want to define how many
> > tags an Entity can have. If an Entity can have more than one tag, I'd
> > explicitly state what that max is. Write out everything you need when
> > the user submits an entity, so that your reads will be fast as other
> > users browse the site.
> >
> > Mark
> >
> > On Jul 19, 9:16 am, planetjones <[email protected]> wrote:
> >
> >
> >
> > > Hi,
> > > I'm looking to store entities using GAE Java which have 1-many tags.
> > > I
> > > would like to display a tag cloud, so will need to know how many
> > > times
> > > each tag occurs (can't use aggregate functions and group by on GAE to
> > > do this like I would in SQL). And when I click a tag I would like to
> > > retrieve all entities with the selected tag.
> > > Does anyone have any examples of what my Classes should look like to
> > > do this optimally and efficiently? Sample JPA code would be great
> > > too.
> > > Cheers - Jonathan
>
> --
> 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
> [email protected].
> To unsubscribe from this group, send email to
> [email protected]<google-appengine-java%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/google-appengine-java?hl=en.
>
>

-- 
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 [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-java?hl=en.

Reply via email to