I was having the same problem using the searchable plugin on a recent Grails application I was developing. I had two domain objects, with a one to many relationship, that I was indexing to be searched. For simplicity I'm just showing the Domain objects with their fields and relationships. I am not showing any mapping or constraint information. Here are my original classes
class CodeValue{
static searchable ={
only:['value', 'description']
value boost: 2.0
}
String value
String description
static belongsTo = [codeset: CodeSet]
}
class CodeSet{
static searchable ={
only:['name', 'description']
name boost: 2.0
}
String name
String description
static hasMany = [codeValues:CodeValue]
}
Searches for CodeValues were taking > 17 seconds. I did have over 1000 CodeValue objects indexed, but a 17 second search time was unacceptable. I figured out what was causing the slow search times and it appeared to be related to the Compass functionality built into the Grails Searchable plugin.
As part of the search, all matched objects are marshalled into the index. For a set of Domain objects in the 100’s the time to perform this marshalling is not too bad, however, when you get into the 1000’s it takes a substantial amount of time. Perhaps the time is also related to complexity of the object being marshalled? Anyway, I found a blog post from a guy having a similar problem as me.
To summarize the article when he was searching 1000+ objects the search time was greater 15 seconds. Just like what I was experiencing.
He mentioned two things:
1)Setting the "supportUnmarshall" option to false, default value is true, in the “static searchable“ configuration in the domain object. By setting this option search matches are not marshalled into the index, however search time is very fast. The down fall to setting this option to false is the results will not contain the objects unmarshalled from the Index, and you have to fetch the matching domain object from the database using the id returned as part of the search result. You would think this would be bad, but it is not, and using this method my search results are actually displayed much faster than before. Here is the URL for the info on setting the supportUnmarshall option http://grails.org/Searchable+Plugin+-+Mapping+-+Class+Mapping. It is the last option in the “Options” section.
2)Enable "reload" in the defaultMethodOptions of the Searchable.groovy configuration file. So put something like this in the Searchable.groovy file:
defaultMethodOptions = [
search: [reload: true, escape: false, offset: 0, max: 25, defaultOperator: "and"],
suggestQuery: [userFriendly: true]
]
You will need to add the Searchable Config plugin to update this value. Details for adding and editing the Searchable.groovy config file can be found on the web page for the Grail Searchable Plugin. Since I do not have a high enough reputation. I cannot post more than two links, so you will need to go to the web page for the Grails Searchable plugin, and look up the documentation on how to install the Searchable Config Plugin.
To give an example of the performance improvement. Previously, searches on CodeValues took 17+ seconds to complete. They are now completed in 0.002 seconds.
The final code I wrote looked like this:
class CodeValue{
static searchable ={
only:['value', 'description']
value boost: 2.0
supportUnmarshall false
}
String value
String description
static belongsTo = [codeset: CodeSet]
}
class CodeSet{
static searchable ={
only:['name', 'description']
name boost: 2.0
supportUnmarshall false
}
String name
String description
static hasMany = [codeValues:CodeValue]
}