Sooner or later, before each site (be it a social network, a forum, a blog or some other repository of information) there is a search problem. Each developer solves this problem in his own way: some write their own solutions, others use ready-made embedded search engines, others use external solutions, for example, services from Google.
In this article, I’d like to talk about a search tool like Ferret and how easy it is to use this solution in my Rails application.
So, ferret is a
high-performance search engine for Ruby, based on
Apache Lucene . Installing ferret comes down to a set of one single command:
')
gem install ferret
Ferret is an engine designed for Ruby as a whole, and not just for Rails applications. Using it in Rails is easier than you can imagine. To integrate Rails and Ferret, you need to install the
Acts As Ferret plugin in your project. Go to the project folder and type the following in the command line:
ruby script/plugin install svn://projects.jkraemer.net/acts_as_ferret/tags/stable/acts_as_ferret
In order to use Ferret, you need to do the following: in the model (suppose we want to index users, or rather their first and last name), by which we want to perform full-text search, we add the following lines:
class Member < ActiveRecord::Base
acts_as_ferret :fields => [:first_name, :last_name]
end
After that, Ferret will index the Member model table. Now consider how to search.
The easiest way is to use the
find_id_by_contents method. So, if we write the following instruction:
total_results, members = Member.find_id_by_contents("Egor")
Then the following will happen:
- folder index / development / member is created in which indexes will be placed
- each time participants are added, removed, or updated, indexes will be updated (without any additional instructions from the developer). If for some reason you need to forcefully update all indexes, simply delete the index / development / member folder and the indexes will be forced to be updated.
- ActAsFerret will call the Search_Each function .
- the function returns the total number of records found, as well as the first 10 of them in the following format
members = [
{:model => "Member", :id => "4", :score => "1.0"},
{:model => "Member", :id => "21", :score => "0.93211"},
{:model => "Member", :id => "27", :score => "0.32212"}
]
You can ask what to do if you want to get more than 10 results? The answer is simple: the
find_id_by_contents function has several parameters that allow you to control its behavior:
- offset - indicates the position from which the results will be returned
- limit - the number of returned records
Of course, the function
find_id_by_contents can be used with a block, like this:
results = []
total_results = Member.find_id_by_contents("Egor") {|result|
results.push result
}
Or, if we want to get records from the database, and not just identifiers, then we can do this:
results = []
total_results = Member.find_id_by_contents("Egor") {|result|
results.push Member.find(result[:id])
}
To solve the latter problem, there is a simpler way: using the
find_by_contents function.
@results = Member.find_by_contents("Egor")
So what does this instruction do?
- calls the find_id_by_contents function to get ids
- get results from the database by identifiers found
- returns an object of class ActsAsFerret :: SearchResults which is essentially a small add-on over an array of ActiveRecord elements
As you can see, using Ferret is quite simple and convenient, at the same time, it fits perfectly into the Ruby and Ruby On Rails ideology, so this tool can become an indispensable tool for organizing searches in your project.
Ps in order to learn about such tasks related to Ferret, as:
- pagination
- advanced search
- indexing custom fields
- write results
- search result highlighter
- installation of various scales for various fields of model
I recommend to look in more detail
this manual (I actively used it for writing of this article), and also the
official site of the project