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 Blogs 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!