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:
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}
Bình luận