Configuring Elasticsearch On Rails
Pre-requisites:
- Rails version 4+
- Elasticsearchsearch version 2.3.2
Make sure you have elasticsearch running.
elasticsearch #on mac
brew services start elasticsearch #on mac
sudo service start elasticsearch #on linux
there are a lot of gem available for integration of elasticsearch with rails. The gem that I am using is called “elasticsearch-rails”.
Install the gem:
In your Gemfile.rb write the following:
gem 'elasticsearch-rails'
save the file and then run
bundle install
Then in the directory app/config/initializers/ make a file “elasticsearch.rb”
and write the following:
config = {
host: "http://localhost:9200/",
transport_options: {
request: { timeout: 5 }
}
}
if File.exists?("config/elasticsearch.yml")
config.merge!(YAML.load_file("config/elasticsearch.yml")[Rails.env].deep_symbolize_keys)
end
Elasticsearch::Model.client = Elasticsearch::Client.new(config)
Note: changing symbolize_keys to deep_symbolise_keys as suggested by Sylvain Mina (it will make sense if one has nested configurations)
If you want to specify, say, different urls for different environments, you can do so by creating a file “elasticsearch.yml” in directory app/config/
and writing something like
development: &default
host: 'http://localhost:9200/'
transport_options:
request:
timeout: !!integer 300test:
<<: *default
staging:
<<: *default
production:
host: 'http://10.50.11.50/'
transport_options:
request:
timeout: !!integer 300
The configuration is all done.
Now to use elasticsearch in your models, you have to do the following:
Let’s say there is a model called User. In user.rb:
class User < ActiveRecord::Base
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks.
.
.
end
Next define the name of the index in User.rb:
index_name([Rails.env,base_class.to_s.pluralize.underscore].join('_'))
Next, make sure you have some records loaded in the model.
Then from the Rails console, run the following to import all the user records in elasticsearch.
Note: Make sure elasticsearch is running before importing data.
#to get into the rails console use rails c
User.import(force: true)
You are ready to start searching !!
To search you need to pass the query to search method of Elasticsearch.
#this will return an array of records
User.search("divyanshu").records
By default, Elasticsearch indexes all the attributes present in your model. However, the same can be changed. This is done by modifying the method as_indexed_json().
- Indexing selective attributes: This can by done using “only” option which accepts a single value or an array of values. You can specify which attributes you want to be indexed.
#define this method in User.rbdef as_indexed_json(options={})
as_json(
only: [:first_name, :email]
)
end
Save the file and in the “rails console” type the following to get a fresh import.
#this is used to delete index
User.__elasticsearch__.delete_index!#this is used to create index
User.__elasticsearch__.create_index!#this is used to import the data into Elasticsearch
User.import #note: No need to pass force: true to import#to the indexed data of first record
User.search("divyanshu").records.first.as_indexed_json
2. Indexing associations: this is done using “include” option