Học lập trình Ruby on Rails trực tuyến
ElasticSearch-Rails

Trong bài viết mình chia sẻ cách áp dụng ElasticSearch - công cụ hỗ trợ tìm kiếm (gần như) thời gian thực - vào ứng dụng Ruby on Rails - Framework tạo web nhanh chóng, dễ dàng. Bài viết sẽ đi trực tiếp vào cách làm, trên môi trường Ubuntu.

Cài đặt ElasticSearch

  • Các bạn download file ZIP tại: https://www.elastic.co/downloads/elasticsearch
  • Giải nén, cd tới thư mục elasticsearch
  • Setup ElasticSearch:  bin/elasticsearch
  • Kiểm tra server ElasticSearch: curl -X GET http://localhost:9200/
  • Nếu thành công, bạn sẽ nhìn thấy màn hình:

Học lập trình Ruby on Rails chất lượng

Note: Nếu bạn gặp lỗi về JDK, hãy kiểm tra lại để chắc chắn bạn sử dụng cùng version jdk và jre

sudo update-alternatives --config java

sudo update-alternatives --config javac 

 

Áp dụng ElasticSearch vào ứng dụng Ruby on Rails

 

  • Trước hết, các bạn cần thêm 2 gem dưới vào Gemfile và bundle

gem 'elasticsearch-model'
gem 'elasticsearch-rails'
  • Tạo file:  concerns/searchable.rb
#app/models/concerns/searchable.rb

require 'elasticsearch/model'

module Searchable
  extend ActiveSupport::Concern

  included do
    include Elasticsearch::Model
    include Elasticsearch::Model::Callbacks

    def self.search_by(type, query)
      self.search("#{type}:#{query}")
    end
  end

end
  • Include Searchable Model vào model
# app/models/user.rb

class User < ActiveRecord::Base
  include Searchable
...
end
  • Create lib/tasks/elasticsearch.rake và add đoạn code sau:
    require 'elasticsearch/rails/tasks/import'

     

  • Chạy rake command trên terminal để import data từ model vào ElasticSearch 
rake environment elasticsearch:import:all
  • Bạn có thể sẽ chỉ muốn index một số fields nhất định của Model để giảm bộ nhớ cho ElasticSearch
# app/models/user.rb
class User < ActiveRecord::Base
...
  def as_indexed_json(options = {})
    self.as_json({
      only: [:name, :email],
      include: {
        books: { only: :name }
      }
    })
  end
end

Test bằng Rails Console

User.search('*').map { |u| u.name }

User.search('ColinDao').records.to_a

User.search('Tech Master').results.total

@users = User.search(params[:q]).page(params[:page]).records

response = User.search query: {match: {name: 'Tech Master'}}

# Nếu bạn muốn sử dụng partial query , bạn có thể tìm hiểu về query string query
# Bạn cũng có thể truyền params page và size để request
Book.search(query: { query_string: {query: "title: *Ruby*"}}, size: 15, from: 2).records.map{|b| b.price}