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.
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
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.
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 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
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.
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