views:

28

answers:

1

I'm using the datastore of the Google App Engine (DataNucleus). I have two classes, one Chat and one Rating. A chat can be rated more then ones so I created an one-many relationship by adding a list to the Chat class.

Now I want to know the number of unrated chats, so I did the following:

int numberOfChatsInStock = 0;
for(Chat chat : chats){
  if(chat.getRatings().size() == 0){
    numberOfChatsInStock++;
  }
}

It simply iterate through all chats and checks if the number of ratings is 0.

This solution works well when there are 10 chats, but when I have 500+ chats then the speed is terrible (15 sec +).

I thought maybe the size() method is faster. So I tried Query.setFilter("ratings.size() == 0") but this gives me the following error: Unsupported method while parsing expression: InvokeExpression{[PrimaryExpression{ratings}].size()}

Is there any way to increase the speed?

EDIT REACTION FROM DATANUCLEUS EXPERT:

This is Google's plugin, and they are responsible for it (and the fact that they haven't implemented that method is their issue ... I'm sure their datastore offers a way of getting a size of a collection). Their plugin only uses DataNucleus 1.1 and we currently develop 2.2 so, as you can guess, we don't have much time for the GAE/J environment.

Why is google using the 1.1 version?

A: 

You should keep a rating count on the Chat model. Then you can run a query to select all chats with 0 ratings.

Robert Kluin
I thought about this earlier but thought this is not the best way to solve the issue because i should keep the count up to date all the time. Anyway, for now i'll work with it, thanks.
Ben
When you are developing for GAE's bigtable (or many other nosql databases) you often need to denormalize and precompute if you want efficient queries. Otherwise you end up having to iterate over lots of data, which may or may not be acceptable.
Robert Kluin