ElasticSearch + Kibana


This post - simple manual about installing and using ES + Kibana stack.

Step 0:

First you need to install ElasticSearch (you can just Google - it’s a simple and installation steps fully depends on your operating system and environment).

Next, let’s install Kibana https://www.elastic.co/products/kibana.

For example for MacOSX it’s a simple http://brewformulas.org/Kibana:

Just run:

brew install kibana

Application specific steps.

Step 1:

Let’s add two gems to Gemfile.

gem 'elasticsearch-model', git: 'git://github.com/elastic/elasticsearch-rails.git', branch: 'master'
gem 'elasticsearch-rails', git: 'git://github.com/elastic/elasticsearch-rails.git', branch: 'master'

Step 2:

Let’s modify our Post model and include ElasticSearch modules.

class Post < ApplicationRecord
 
  ...

  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks
  
  ...

end

Next let’s force import (reindex) all Posts:

Post.import(force: true)

Let’s check our tech index info, just run in Kibana:

GET _cat/indices?v

Here we go:

health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   posts VbH_tIWySKykAQyChEbBTQ   5   1        101            0     67.4kb         67.4kb

Let’s check our Kibana for json output of search request:

kibana

Cool, now our index created, please keep in mind, that this index contains all fields from model.

But what, if we just need to include only specific fields?

We can use settings for this purposes.

class Post < ApplicationRecord
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks

  settings do
    mappings dynamic: false do
      indexes :description, type: :text, analyzer: :english
      indexes :active, type: :boolean
    end
  end
end

As you can see, we added description with text type and english analyzer and active with boolean type fields.

Now let’s create new index and remove old one.

Post.__elasticsearch__.delete_index!

Cool. Now, we want to perform a super fast search with ES using our new index.

For this purposes we can create new class method in_active and just call this method from controller from our search page.

def self.in_active(query)
  self.search({
    query: {
      bool: {
        must: [
        {
          multi_match: {
            query: query,
            fields: [:description]
          }
        },
        {
          match: {
            active: true
          }
        }]
      }
    }
  })
end