I started work on this plugin back in December based on the work I did for Patheos.com and by the graces of my employer Avalon Consulting LLC and Patheos, they allowed me to open source the plugin and continue working on it. This week I had some time to get back to it, and today I started creating a basic reference implementation application that will accompany the documentation. Below is a screencast demo of this application which indexes an export of songs from my iTunes library metadata and makes them searchable.
The code for the plugin is at Github and is still a work in progress. I’m pushing towards a 0.1 release next week with the bulk of the work I still need to do in the form of documentation and clean-up.
So please watch the screencast, and I would love feedback. I will certainly take offers to help continue the development of the plugin but would like to get 0.1 out first to round out my train of thought and not further delay that basic milestone.






A builder like Searchable plugin's query builder would be nicer than instantiating a SolrQuery. i.e. Song.searchSolr(params.q) {
…add faceting here
}
Also a lot of scope to Grails-ify the faceting stuff in the GSP – dynamic properties for facets by fields eg I would go for ${results.response.facetFields[Song, 'genre'].values}
Much nicer I think? By adding the dynamic stuff like this you can make what is quite a big Java API seem like a really natural interface in Groovy.
Would love to decrease the verbosity. I just implemented a call on the result object so you can do this:
result.facet(Solr1, "astring").values
I also want to create a collection of taglibs for constructing style-able search UI. For example:
<solr:facet field="genre"/>
<solr:facet field="year"/>
<solr:search autocomplete="true"/>
<solr:results pageSize="10"/>
Nice work, I'm really interested in using Solr to replace Searchable/Compass in our Grails apps. One immediate question – solrTitle looks like it would be ugly make it i18n aware… isn't there a way to render the title in results in the view layer using data from the result object?
Thanks Marc, The solrTitle method is called on index of the domain and the result of this is stored in the corresponding Solr document under the 'title' field. In my example, you could get the value of the title from the result as ${item.title}
You can override this also if you have an attribute in your domain named title.
And then further, you can define overrides for how it indexes fields by defining methods like indexSolr<attribute_name> like this:
def indexSolrTitle(doc) {
doc.addField(this.solrFieldName("title"), title?.toUpperCase())
}
This would also allow you to index the attribute multiple times so if you had a way to resolve the translation for an attribute you might do something like this.
def indexSolrTitle(doc) {
doc.addField("title_es_s), getSpanishTitle())
doc.addField("title_en_s), getEnglishTitle)
doc.addField("title_fr_s), getFrenchTitle)
}
What do you think? I need to think through the i18n use cases a bit more. Any suggestions for how you would like it to work?
Awesome work Mike!
Could solrAutoIndex be a global property? For instance ALWAYS reindex domain classes by default? And then maybe have a way to disable it globally (for bulk inserts)
The ability to hit the solr instance directly and test queries is really cool. I especially like the ability to see how many items are indexed.
Would be neat to wrap SolrQuery so that it could take a params map like .list() and .findBy() dynamic methods to facilitate pagination – so you could do
def query = new SolrQuery(params.q, params)
you could then look for offset and max in the params map and automatically do the pagination rather than the if statements you had in the controller
A solr paginate tag library that wraps the g.paginate would also be neat to have
Great work – looks really powerful! Can't wait to try it out
I see that there are two Solr plugin in http://grails.org/plugin/, "Solr" and "GSolr". Any relation?
No relation to GSolr, I hadn't seen that… Suspect it is new.
Sent from my iphone
I've sent you an eMail a few days ago. It'd be great if we could work together / contribute in one way or another. Please let me know your thoughts.
Yes, got it, just been busy. I'll respond to your email. Maybe we can hook up on Skype next week and sync up on thoughts/direction.
That would be great
Oops, struggling to post my comment, please delete the last one if possible. Here's my real comment:
I would definitely steer clear from one record with multiple languages in the one record . . . otherwise it might be hard to avoid false positive matches on fields containing text from the wrong language.
Localization is much more interesting than translation, so make the assumption that for each record there may not be an equivalent translation. For example, while a site might be translated into two languages, each language may have a different set of pages, so not every page has a direct translated analogue.
Each record could only have text in one language and have fields indicating the language and relevant locale(s) so results can be filtered by language or locale.
Hy,
just starting to try your nice grails plugin and ran into a problem.
In SolrGrailsPlugin.groovy Line 260 you use delegateDomainObject.getProperty(prop.name)
I use Java Classes as Domain Objects and they do not have a getProperty method.
But grails does add a properties Map.
Changed the Line to ->
def docValue = delegateDomainOjbect.properties[prop.name]
Seems to work at a first glance. (doesnt throw a MissingMethodException
)
Thanks! I'll roll this change in soon and try to get the next version out… time has been a problem.
Would you mind creating a Jira issue for this in the Grails Plugins jira:
https://cvs.codehaus.org/browse/GRAILSPLUGINS
and select Grails-Solr as the component?
Let me know how it goes!
Mike
Robert, just fixed this and released a new version 0.2 – a few other minor fixes in there as well.
Hi,
Great plugin, it really rocks. I found one minor issue, and I'm not sure if it's specific to my environment. I am using grails 1.3.0.RC2, and when I execute grails index-domain <class>, it doesn't do any indexing. However when I modify the IndexDomain.groovy script to rename the "default" target to "index" and add a setDefaultTarget("index") line it works. E.g., lines 34-37 in my IndexDomain.groovy are now:
setDefaultTarget ( "index" )
//target ( default: "Index a domain class") {
target ( index: "Index a domain class") {
. . .
Thanks,
eric
Nice plugin. Good timing too, just started working on a Grails / Solr project. I'll fork you and notify of any significant changes!
Could someone give me a brief hint how to import my iTunes library? Setup was successful, start-solr was successful, run-app was successful, there is a file Library.xml in the projects base directory. What next?
Got it running by myself: with help of http://gist.github.com/423119 "grails run-script scripts/IndexSongs.groovy" finally worked (with grails 1.3.1, which was the problem)
Very nice, gives me a lot of inspiration being right in the midst of a redesign. It? all in the details and comment forms are definitely overlooked more often than not. Time well spent on this post.