Easy search provides a convenient DSL for quickly searching your
What It’s NOT
Firstly, let’s just get this out of the way. EasySearch is not intended for search-intensive or high-performance applications. There are plenty of other (awesome) full-text plugins for that (e.g. acts_as_ferret, sphinx/ultrasphinx, etc). It’s just an easy, quick-n-dirty search for your
ActiveRecord models. So if you’re looking for a search solution to hunt through your 10 million record database, please, leave now while you still can.
So, Why Build it?
Honestly? Because building a DSL interface to a simple thing is fun. It’s actually a lot of fun. Also, I think it’s a reasonable place to start for creating something bigger. Overall, this plugin is more-or-less the result of me toying around with the dynamism of Ruby :-)
You can install this as a Rails plugin. Navigate to your project root and type:
git clone git://github.com/rpheath/easy_search.git vendor/plugins/easy_search
Use it at your own risk. You’ve been warned.
General Use Case
Again, please don’t attempt to use this if you’ll be searching giant databases, as I’d imagine you would need something performance aware, which this is not. But. It should work fine for hundreds, thousands, maybe even tens-of-thousands of records. You know, like blogs, small forums, etc.
In config/initializers/easy_search_setup.rb (or config/environment.rb if you aren’t running Rails 2.0+), you’d do something like this:
EasySearch::Setup.config do setup_tables do users :first_name, :last_name, :email, :login projects :title, :description comments :name, :body groups :name, :description end end
setup_tables method allows you to specify which columns should be searched for each one of your tables. It’s required if you want to use
EasySearch with one of your models. Otherwise,
EasySearch wouldn’t have a clue what to do with your keywords.
And of course, should you try to search a model that has not been configured,
EasySearch will let you know :-)
We’ll go straight into it. First thing, you install the plugin. Then you add a generic class and give it the
EasySearch functionality. Like so:
# app/models/search.rb class Search include EasySearch end
Now we have a
Search class that can easily handle search your
ActiveRecord models! Notice how this class does not descend from
In words, let’s say we want to “search the users table with ‘ryan heath’”. To represent that in code, it’s basically the same thing:
$> Search.users.with('ryan heath') $> => [<#User ...>] $> Search.projects.with('webdesign') $> => [<#Project ...>, <#Project ...>, ...]
Note: the above will not compare ‘ryan heath’ with each of the configured columns, but it will compare ‘ryan’ and ‘heath’ separately against each of those columns for better results. Another thing worthy of mention about keyword splitting: it’s slightly more sophisticated, in that it will strip out the dull keywords that would return innaccurate results, which also helps performance. For instance:
You can also search by an exact phrase. Let’s say you wanted to support a search for ‘“ryan heath”’, where you didn’t want EasySearch to search “ryan” and “heath” separately. Well, all you have to do is tell your users to wrap their search terms in quotes (just like Google) and EasySearch will know to search that phrase, in that order, without splitting up the words.
Search.users.with('ryan and a term')
That would only search ‘ryan’ and ‘term’ against your columns.
EasySearch tries to be somewhat smart about what it searches. And in fact, you can see what
EasySearch considers “dull keywords” by doing:
# default dull keywords (this is just an example) $> EasySearch::Setup.dull_keywords $> => ['a', 'and', 'the']
The list is far from complete. So if you have words that you’d like to add to the “dull keywords” list (meaning words that would not be searched), you can do so quite easily. Going back to the
EasySearch::Setup.config do strip_keywords do ['what', 'then', 'if', 'is', 'it'] end end # dull_keywords is now a sum of the defaults plus your custom keywords $> EasySearch::Setup.dull_keywords $> => ['a', 'and', 'the', 'what', 'then', 'if', 'is', 'it']
Those keywords are appended to the existing list (all duplicates are removed). And if you’d rather your custom list replace the existing defaults entirely, just pass ‘true’ to the
strip_keywords method, like so:
EasySearch::Setup.config do strip_keywords(true) do ['what', 'then', 'if', 'is', 'it'] end end # dull_keywords is now only your custom keywords $> EasySearch::Setup.dull_keywords $> => ['what', 'then', 'if', 'is', 'it']
And finally, if you have additional conditions that you need to apply to all search results, just use a :conditions option on the
with method, like so:
$> Search.users.with('ryan heath', :conditions => 'active => 1') $> # active users matching 'ryan' and/or 'heath'
Pretty easy, huh?
Again, this plugin is not meant for searching high-volume Databases. It doesn’t handle indexing or any of the other things a full-text solution might handle. But it was a fun plugin to write, and it’s a fun API/DSL to use, and that’s why I wrote it.
Copyright © 2008 Ryan Heath, released under the MIT license