Alphanumeric Sorting using Criteria Query (with MySQL database)
I am working on a Grails application with MySQL database. I had a use case in which I had to implement alphanumeric sorting using Criteria Query on Grails. By alphanumeric sorting I mean if there is a class Employee with field empId then on doing :
[plain]
Employee e1 = new Employee(empId:’emp10′).save()
Employee e2 = new Employee(empId:’emp2′).save()
Employee e3 = new Employee(empId:’emp1′).save()
Employee e4 = new Employee(empId:’1emp’).save()
Employee e5 = new Employee(empId:’10emp’).save()
Employee e6 = new Employee(empId:’2emp’).save()
Employee.createCriteria().list([sort:’empId’])
/* OR */
Employee.createCriteria().list{
order(’empId’)
}
[/plain]
should give result like [e4,e6,e5,e3,e2,e1]. But according to sql sorting the result would be [e5,e4,e6,e3,e1,e2]
One thing to note was that criteria query implemented sorting at the database end.
After googling around, I came across a script that had a SQL function which converted the field value to string that can alphanumerically sorted easily at database end.
To migrate the functions in script to database you have to unzip the script and write following command on terminal:
[shell]mysql -u username -p database_name < /path/to/unzipped/directory/natsort.install.mysql[/shell]
Now only thing I had to do was to get a derived field from the Grails property that had to be sorted alphanumerically which was easily possible as the Grails had ability to create transient field using formula (thanks to wonderful Blog by Uday). Thus I had to create a new transient field using SQL function in formula. So I did something like this :
[groovy]
class Employee {
String empId
String empIdSortField //transient field
static mapping = {
empIdSortField formula: ‘natsort_canon(empId, "natural")’
}
}
[/groovy]
Now if I had to get Employee objects are sorted by empId alphanumerically, what I would do is :
[groovy]
Employee.createCriteria().list {
order(’empIdSortField’)
}
[/groovy]
Hope this was helpful to you!
Hi there, nice article! Any change to see a groovy implementation of the natural sort algorithm? This is really cool if you’re working on a Domain class, but what if you need to sort something different like a list of files by file name?
Hi Michael,
Thats what the SQL function in script is doing here at the database end.
And if you are talking about persisting the sort field then it might make table huge in case the there are multiple fields in table that need to be sorted in such way.
Don’t you get this by simply creating a sort field where you pad out any number to the same length (eg emp01, emp02, emp10, 01emp, 02emp, 10emp)?