Nick Johnson's newsgroup e-mail explains pretty much what you need.. except he leaves out some details (don't know, maybe he was busy building out the Appengine subsystem at the time or something) explaining exactly how to set it up underneath.
You should probably try something like this (which I believe is what Mr Johnson's example uses underneath). I use Python so you're on your own with Java, but the concept is identical (I'm doing this the lazy way so there is no thought put to what property types should be used.):
class baseEmail(db.Model):
From = db.StringProperty()
To = db.StringProperty()
Subject = db.StringProperty()
Message = db.StringProperty()
TimeStamp = db.DateTimeProperty()
Attachment = db.BlobProperty()
class metaEmail(db.Model):
Status = db.StringProperty()
From = db.StringProperty(indexed=False)
Subject = db.TextProperty()
TimeStamp = db.DateTimeProperty()
I haven't bothered with thinking too deeply about the "right" ways to pick property types.. or whether to mark some as indexed=False.. but this gets the core concept.
For this example, baseEmail.key().name() == metaEmail.key().name() (but they don't need to be in some child parent relationship or anything silly like that.. you don't need transactions for this).
When a user clicks "Refresh" to see if they have more messages.. a process runs that does something like this:
newEmails = db.baseEmail().all().filter('TimeStamp >', MaxMetaEmailTimeStamp).fetch()
newMetaEmails = []
for email in newEmails:
metaEmail = metaEmail(key_name = email.key().name(), Status = 'Unread', From = email.From, Subject = email.Subject, TimeStamp = email.TimeStamp)
newMetaEmails.append(metaEmail)
db.put(newMetaEmails)
And, at the same time.. it displays the newMetaEmails on screen.
Now, there are more and more optimizations to add (you could use ReferenceProperty with this if you want tighter associations).. but this is the core idea..
You have metaEmail which is just metadata pointing to the underlying baseEmail data.. make metaEmail as small as possible.. if you don't need Subject or other stuff... leave those off.. the only properties you really need are Unread and TimeStamp.
You can change the metaEmail.Status to 'Deleted' for deleted emails.. and only truly delete them once every 24 hours or something.. this would allow for a handy undelete option.. etc.
My bad. I forgot to mention, there would be an option where I show just the 'unread' tweets to the user or just the 'read' tweets. When I show all tweets, your example would work perfectly fine. But what about the other two scenarios? Any pointers would help. I use GAE/J.