Peter Marklund

Peter Marklund's Home

Fri November 02, 2007
Programming

Rails Search Plugin Review: acts_as_fulltextable

The other day I had the opportunity to install and evaluate the recently announced acts_as_fulltextable Rails plugin. The raison d'etre of the plugin is to offer easy access to the MySQL full-text search engine. The plugin uses a FulltextRow ActiveRecord model stored in a MyISAM table with a polymorphic reference (id and model name) to the model that you want indexed and a single column to hold the search index text. All you need to do is basically add an acts_as_fulltextable declaration to the model that you want to search and this will then create a has_one :fulltext_row relationship and the appropriate callbacks to populate the index on create, update, and delete.

The acts_as_fulltextable plugin mostly exceeded my expecations, especially in terms of easy setup and maintenance. It makes site-wide search (across all models) as well as model specific search (constrain your search to one or more models) very easy. A strength of the plugin is the simplicity. There is very little code and the architecture is straight forward and easy to grasp.

Something to be aware of is that MySQL uses OR searches by default. I wanted to follow the Google convention of AND searches and found myself having to prefix all query terms with a plus sign to accomplish this. Is there a better way? A more serious issue is that MySQL doesn't seem to support word stemming. It turns out that the acts_as_fulltextable plugin does a gsub on search queries to add a trailing * to each search term. MySQL calls this truncation. The star ("*") works as a wild card. If you are aware of this feature you can use it to manually work around the absence of stemming, just search for house* and that will match both "house" and "houses". It will also match "household" which may or may not be what you want.

A documented gotcha that I ran into is that if you combine the leading plus sign and the trailing star (i.e. use both boolean AND and truncation) then stop words will not be removed from your query and thus you may end up with zero results. This is very annoying. What is the solution? I don't know. Maybe go with OR searches, live with the stemming issue (without the star), or find a way to remove stop words yourself. Stop words are supposedly configurable in MySQL.

The acts_as_fulltextable plugin was created because of stability issues with Sphinx and Ferret and because Solr was considered overkill. Lucene/Solr appears to be the most well documented, reliable, scalable, and flexible open source search engine out there. My guess is that Solr is still your best best if you are a search power user and your requirements are high. Because of its simplicity and ease of maintenance though, acts_as_fulltextable offers a pretty attractive lower end alternative.

Comments

Michele said over 6 years ago:

Hey Peter, glad you like the plugin.

We know there are a few gotchas here and there, but in the end we decided to put up with them. :)

BTW, Solr is definitely the best beast around (especially when it comes to stemming...it works magnificently), unfortunately it's too powerful for most needs.
So, if you need basic full-text search, go the the acts_as_fulltextable route, otherwise, try Solr (Sphinx is great, too, it's a tad less customizable than Solr, but is very fast and efficient).

--------------------------------------------------------------------------------

Brian said over 6 years ago:

Hey Peter, thanks for the info. I'm researching plugins at the moment. Btw, I'm not really familiar with the difference between a fulltext search and other types. Don't forget to explain the basics too! ;)
Brian

--------------------------------------------------------------------------------

rpg said over 6 years ago:

Yeah i am not quite sure either to understand the basics. Is full text search when you try to match all the words supplied? I really have to take a break this summer and learn more about rail/prog, i found out that plugins often are not plug and play, i guess it's part of the game :P

--------------------------------------------------------------------------------