Incorporate Elasticsearch into your Rails app

What is Elasticsearch?

Elasticsearch is an OSS full-text search engine developed by Elastic. You can quickly extract a document containing the desired word from a large number of documents.

The idea of working with Elasticsearch in Rails apps

  1. The full-text search engine contains the data to be searched.
  2. When searching on the application side, a query is issued to the search engine and the result is returned.
  3. When the data to be searched is updated on the application side, the data of the search engine is also updated in cooperation.

Working with Elasticsearch in Rails apps

Create an index

Elasticsearch creates an index as a storage location for your data. It's like a table in a relational database.

First, install a dedicated gem to handle Rails models in Elasticsearch. Write the following in Gemfile and bundle install.

gem 'elasticsearch-model', github: 'elastic/elasticsearch-rails'
gem 'elasticsearch-rails', github: 'elastic/elasticsearch-rails'

After bundle install, create an index in Elasticsearch. Include Elasticsearch :: Model in the model you want to search.

class Article < ActiveRecord::Base
  include Elasticsearch::Model
end

Your model is now ready to work with Elasticsearch. You can create an index with code like this:

Article.__elasticsearch__.create_index! force:true

Put the document in the index

In Elasticsearch, the data in the index is called a document. Enter the data you want to search in the index.

Import the document into Elasticsearch with the following code.


Article.import

The document will now be registered in the Elasticsearch index.

Search documents

To search the document, submit a query to Elasticsearch. You can query Elasticsearch from Rails by writing:

response = Article.search 'hoge'

You can search the document by specifying the search string as an argument.

If you receive the parameters from the front desk and search, you can write as follows.

def index
  @articles = Article.search(params)
end

When the record to be searched is updated on Rails side, the Elasticsearch document is also updated accordingly.

When it comes to actually operating the service, it is necessary to update the Elasticsearch document when the record is updated on the Rails side.

First of all, to simply update the Elasticsearch documentation, implement:

Article.first.__elasticsearch__.update_document

There is another method called delete_document, which you can use to delete a document.

You can also update the document automatically when you update the record, without having to write it explicitly as above. In elasticsearch-model which is a gem, if Elasticsearch :: Model :: Callbacks is included in Model, it will send a query to update the Elasticsearch document when the record is updated.

class Article
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks
end

Incorporate Elasticsearch into your Rails app

Actually create the processing around the search of the Article model.

article-m/app/models/concerns/article/searchable.rb


require 'active_support/concern'
module Article::Searchable
  extend ActiveSupport::Concern

  included do
    include Elasticsearch::Model
    
    index_name "article"

    settings index: {
      number_of_shards: 1,
      number_of_replicas: 0
    } do
      mapping _source: { enabled: true } do
        indexes :id, type: 'integer', index: 'not_analyzed'
        indexes :title, type: 'string'
        indexes :content, type: 'text'
      end
    end
  end

  module ClassMethods
    def create_index!(options={})
      client = __elasticsearch__.client
      client.indices.delete index: "article" rescue nil if options[:force]
      client.indices.create index: "article",
      body: {
        settings: settings.to_hash,
        mappings: mappings.to_hash
      }
    end
  end
end

In the module, include Elasticsearch :: Model to use convenient methods.

Write the index name in index_name and the index settings in settings. number_of_shards and number_of_replicas are shard and replica settings related to fault tolerance and performance.

mapping determines how the index is defined. It's like a table schema in an RDB.

create_index! is a helper that actually creates an index. Since elasticsearch.client can take the object of Elasticsearch client, You can perform various operations via this client.

Include the created module in the model.

article-m/app/models/article.rb


class Article < ActiveRecord::Base
  include Article::Searchable
  def self.search_message(keyword)
    if keyword.present?
      query = {
        "query": {
          "match": {
            "message": keyword
          }
        }
      }
      Article.__elasticsearch__.search(query)
    else
      Article.none
    end
  end
end

Assemble a search query from the keywords you received and pass it to Article.elasticsearch.search. By calling elasticsearch.search on the Article model, elasticsearch-rails and elasticsearch-model will throw a query.

The controller looks like this:

article-m/app/controllers/articles_controller.rb


class ArticlesController < ApplicationController
  def search
    @keyword = params[:keyword]
    @articles = Article.search_message(@keyword).paginate(page: params[:page])
  end

The above is an example of incorporating Elasticsearch into a Rails app.

reference

Run Elasticsearch on Rails using elastisearch-rails [for beginners] [Summary of what I did to incorporate Elasticsearch into the Rails app search process](https://qiita.com/minamijoyo/items/31118d4aa3d06513ad4d#elasticsearch%E3%82%92rails%E3%82%A2%E3%83% 97% E3% 83% AA% E3% 81% AB% E7% B5% 84% E3% 81% BF% E8% BE% BC% E3% 82% 80)

Recommended Posts

Incorporate Elasticsearch into your Rails app
Incorporate circleCI into CircleCI Rails app
Incorporate Docker into your Ruby on Rails portfolio!
Deploy your Rails app on Heroku
Incorporate existing C / C ++ code into your Android application
Use pagy for pagination in your Rails app.
Rails + ElasticSearch Survey Memo
Heroku app moving (rails)
Delve into Rails form_with
[Core ML] Incorporate an automatically generated ML model into the app
How to deploy jQuery in your Rails app using Webpacker
Make your own Rails validate
[Rails] New app creation --Notes--
Make your own Elasticsearch plugin