Mike has done some great sleuthing on how to use Grails uber-cool searchable plugin to search a domain class based on properties of a nested class.
This is exactly what I’ve been looking for! Gravl supports multiple blogs per install, and when you are viewing my blog, I want those seaches to be constrained to fulltext search of just my blog, not all the data in the blog db.
My data model is 1:M from Blog
to BlogEntry
with a bidirectional link for navigation… So to make it all searchable I’ve got…
class Blog { static hasMany = [ blogEntries : BlogEntry, tags : Tag, blogProperties : BlogProperty ] static searchable = true // ... } class BlogEntry { static hasMany = [ comments : Comment, tags : Tag ] static belongsTo = [ Blog ] // we only index title and body, but index all fields in the parent "blog" static searchable = { title() body() blog(component: true) } Blog blog //... }
So by marking blog(component: true)
we’re telling Compass to store Blog
s fields in the index with the BlogEntry
. Why do we want to do that? So we can search BlogEntry
and impose criteria related to Blog
. In my case, I want to do “find me all BlogEntry objects which contain the text ‘blah’ but limit the hits to those objects that have a blog.blogid of ‘glen’”. The code is simpler than the explanation! Here’s my whole search controller code which powers my search box:
def search = { def query = params.query def blogid = params.blog def results = BlogEntry.search(query + " +blogid:${blogid}", params) return [ results: results, query: query ] }
And you’re got yourself blog-specific searching… Note that “blog.blogid” becomes just “blogid” in terms of field searching (ie. the component objects fields are collapsed into the parent).
Thanks Mike! Great pickup!