I want to be able to do complex searches on grails objects. This is presently implemented using stored procedures on my site that build up a SQL query and parses all of those results.
Will something like the searchable plugin allow me to simplify this task? My guess is not, since it mostly is doing text based searching. The stored procedures are quite complex, and hard to change. Our users are employees, and the queries have to do with amounts of job experience and who they were working for, what skills they have, etc. The Employee domain object would have things like a list of roles that contain skills. The role would have a start and end date, etc.
A list of example queries:
All users with 5 years of experience in C++
All users who have worked for Stackoverflow, in California
All users who have at least 5 years of C++ experience, at least 2 years of Java experience, have worked for StackOverflow, and are available to work now.
I've never tried the searchable plugin so may be selling it short. Your best bet is probably HQL queries or Hibernate criteria builder. I like HQL for complex queries since it's similar to SQL. For a blog post comparing the use of these technologies from Grails see
http://blog.xebia.com/2008/06/04/querying-associations-in-grails-with-hql-criteria-and-hibernatecriteriabuilder/
For the HQL reference see
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html
For Hibernate criteria see
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html
You could also have a look at the FilterPane plugin to help you (or the user) to build these queries. There is a GUI that can handle most of such questions, or you could resort to add the FilterPane fields yourself in the HTML and controller if you prefer to have the control over the queries.
FilterPane then translates the fields to Hibernate criteria builder internally.
All of the queries you have listed can be accomplished with the searchable plugin.
I believe you CAN do the queries you have suggested with HQL but Compass/Lucene is really the better tool for that solution
In my experience HQL queries were the only solution for complex queries.
Some queries even made it necessary to use non-Hibernate functions of the underlying DB, e.g. setting dialect = "org.hibernate.dialect.ExtendedMySqlDialect"
in DataSource.groovy and then implementing something like this:
package org.hibernate.dialect;
import org.hibernate.Hibernate;
import org.hibernate.dialect.function.*;
public class ExtendedMySqlDialect extends MySQL5InnoDBDialect {
public ExtendedMySqlDialect() {
registerFunction("timeStampAdd", new SQLFunctionTemplate(Hibernate.TIMESTAMP, "TIMESTAMPADD(?1, ?2, ?3)"));
registerFunction("timeStampDiff", new SQLFunctionTemplate(Hibernate.INTEGER, "TIMESTAMPDIFF(?1, ?2, ?3)"));
}
The above functions might also help you when dealing with dates.