ElasticSearch with Ruby on Rails
Elasticsearch is a platform for distributed search and analysis of data in real time. Its popularity is due to its ease of use, powerful features, and scalability. Elasticsearch supports RESTful operations. This means that you can use HTTP methods (GET, POST, PUT, DELETE, etc.) in combination ...
Elasticsearch is a platform for distributed search and analysis of data in real time. Its popularity is due to its ease of use, powerful features, and scalability.
Elasticsearch supports RESTful operations. This means that you can use HTTP methods (GET, POST, PUT, DELETE, etc.) in combination with an HTTP URI (/collection/entry) to manipulate your data. The intuitive RESTful approach is both developer and user friendly, which is one of the reasons for Elasticsearch's popularity.
Elasticsearch is a free and open source software with a solid company behind it — Elastic. This combination makes it suitable for use in anywhere from personal testing to corporate integration.
This article will introduce you to Elasticsearch and show you how to use it with ruby on rails.
How to install elasticsearch
First, you will need a Java Runtime Environment (JRE) on your pc because Elasticsearch is written in the Java programming language. Elasticsearch requires Java 7 or higher. Elasticsearch recommends Oracle JDK version 1.8.0_73, but the native Ubuntu OpenJDK native package for the JRE works as well.
$ sudo apt-get update
After that, you can install OpenJDK with the command:
$ sudo apt-get install openjdk-7-jre
To verify your JRE is installed and can be used, run the command:
$ java -version
When you advance in using Elasticsearch and you start looking for better Java performance and compatibility, you may opt to install Oracle's proprietary Java (Oracle JDK 8).
$ sudo add-apt-repository -y ppa:webupd8team/java $ sudo apt-get update $ sudo apt-get -y install oracle-java8-installer
Elasticsearch can be downloaded directly from elastic.co in zip, tar.gz, deb, or rpm packages. For Ubuntu, it's best to use the deb (Debian) package which will install everything you need to run Elasticsearch.
Download it in a directory of your choosing with the command:
$ wget https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.2.deb
Then install it in the usual Ubuntu way with the dpkg command like this: (example in Ubuntu)
$ sudo dpkg -i elasticsearch-1.7.2.deb
This results in Elasticsearch being installed in /usr/share/elasticsearch/ with its configuration files placed in /etc/elasticsearch and its init script added in /etc/init.d/elasticsearch.
To make sure Elasticsearch starts and stops automatically with the Droplet, add its init script to the default runlevels with the command:
$ sudo update-rc.d elasticsearch defaults
Last thing that you need to do to run elasticsearch:
$ sudo service elasticsearch start
After you install and run elasticsearch, you need to make sure your elstatic search work or not you can test it with this
$ curl -X GET 'http://localhost:9200'
and the result that you got from it is:
{ "status" : 200, "name" : "Sultan", "cluster_name" : "elasticsearch", "version" : { "number" : "1.7.2", "build_hash" : "e43676b1385b8125d647f593f7202acbd816e8ec", "build_timestamp" : "2015-09-14T09:49:53Z", "build_snapshot" : false, "lucene_version" : "4.10.4" }, "tagline" : "You Know, for Search" }
Apply elasticsearch with ruby on rails
We will start with a simple rails application as below.
Create the Rails App
Type the following at the command prompt:
$ rails new elasticsearch_rails $ cd elasticsearch_rails $ bundle
Create the Movies Controller
Create the movies controller using the Rails generator, add routes to config/routes.rb, and add methods for showing, creating, and listing movies.
$ rails g controller movies
Then open config/routes.rb and add this resource:
Rails.application.routes.draw do resource :movies end
Now, open app/controllers/movies_controller.rb and add methods to create, view and list movies.
<h1>New Movie</h1> <%= form_for :movie, url: movies_path do |f| %> <% if not @movie.nil? and @movie.errors.any? %> <div id="error_explanation"> <h2><%= pluralize @movie.errors.count, "error" %> prohibited this movie from being saved:</h2> <ul> <% @movie.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <p> <%= f.label :title %><br> <%= f.text_field :title %> </p> <p> <%= f.label :text %><br> <%= f.text_area :text %> </p> <p> <%= f.submit %> </p> <% end %> <%= link_to "<- Back", movies_path %>
Show Single Movie
Create another file at app/views/movies/show.html.erb
<p> <strong>Title:</strong> <%= @movie.title %> </p> <p> <strong>Text:</strong> <%= @movie.text %> </p> <%= link_to "<- Back", movies_path %>
List All movies Create a third file at app/views/movies/index.html.erb.
<p> <strong>Title:</strong> <%= @movie.title %> </p> <p> <strong>Description:</strong> <%= @movie.description %> </p> <%= link_to "<- Back", movies_path %>
You can now add and view movies. Make sure you start the Rails server and go to http://localhost:3000/movies. Click on “New Movie” and add a few movies. These will be used to test our elastsearch capabilities.
Add Basic Search Gem For ElasticSearch
Create a controller called search, along with a view so you can do something like: /search?q=ruby. So we will use gem in rails application, however we have a lot gem that use with elasticsearch as below:
- gem "searchkick"
- gem "chewy"
- gem "elasticsearch-model"
- gem "elasticsearch-rails"
With this article I will use gem elasticsearch-model and gem elastisearch-rails. Let's add it into your gem file and run bundle install.
Add Search Controller
Create search controller
$ rails g controller search
Add method below into app/controllers/search
def search query = params[:q] @movies = query.nil? ? [] : Movie.search(query) end
Integrate Search into Movie
To add the ElasticSearch integration to the Movie model,require 'elasticsearch/model' into config/application.rb and include the main module in Movie class.
class Movie < ApplicationRecord include Elasticsearch::Model include Elasticsearch::Model::Callbacks end
Search View
Create a new file at app/views/search/search.html.erb
<h1>Movies Search</h1> <%= form_for search_path, method: :get do |f| %> <p> <%= f.label "Search for" %> <%= text_field_tag :q, params[:q] %> <%= submit_tag "Go", name: nil %> </p> <% end %> <ul> <% @movies.each do |movie| %> <li> <h3> <%= link_to movie.title, movie_path(movie) %> </h3> </li> <% end %> </ul>
Search Routes
Add search routes at config/routes.rb
get "search", to: "search#search"
You can now go to http://localhost:3000/search and search for any word in the articles you created. Note: If you want to import your database movie to search please run rails console
$ Movie.import
Document
- elasticsearch/elasticsearch-rails
- ElasticSearch on Ubuntu
- Source Example