tags:

views:

189

answers:

2

I have a domain class, in which I've defined some methods which give the object a score based on different algorithms (eg. popularity).

I now want to retrieve a list of these objects sorted by one of these scores (eg. descending by popularity score).

Is there a way to do with with GORM?

Example class:

class SomeObject {
    String title

    Integer popularity() {
     //some algorithm
     return popularity
    }
}
A: 

There are three solutions I can think of. Assuming your dataset is small you can just return the entire list then sort it. For example

objectList.sort{popularity()}

Note based off the following link. http://jlorenzen.blogspot.com/2008/05/groovy-sort-list.html

If the calculation formula is simple you can always use a HQL query instead of the default find by methods. HQL is a query language similar to SQL that works on Hibernate objects which is what Gorm is built on. For more info see the following link. http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html If you don't need the calculated field to be updated in real-time and your calculations are to complex for HQL you can schedule a job to update the calculation results every hour or so, then store the generated result in a field of your domain class. For more information on Grails job scheduling see the following link. http://grails.org/Job+Scheduling+%28Quartz%29

Jared
Hey Jared, actually this kind of answers my question indirectly. This method sorts a list of object properly, but to display the top ten objects, you'd have to pull all records, then sort, which has obvious performance implications.Popularity should have it's own column, and should be updated when the algorithmic factors change. I think that's the only way to limit the query by popularity at the DB level.This is a very handy tip though, thanks!
Thody
A: 

Jared and you are right. Since it's a calculated value and not stored in the DB, GORM has no way of knowing anything about it. If you do as you say and create a new column for the value and then update it as needed you can use the SomeObject.list(order:'desc', sort: 'popularity', max:10) syntax.

Matt Lachman