Hướng dẫn sử dụng elasticsearch với Ruby On Rails
1) Cài đặt elasticsearch
Làm theo hướng dẫn tại trang chủ của elasticsearch
2) Cài đặt gem hỗ trợ tương tác với elasticsearch
Bổ sung vào Gemfile:
gem 'elasticsearch' , git: 'git://github.com/elasticsearch/elasticsearch-ruby.git'
gem 'elasticsearch-model' , git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
gem 'elasticsearch-rails' , git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
Chú ý:
Có 1 gem khác dễ sử dụng hơn là searchkick .
Bài viết này chỉ hướng dẫn cách sử dụng bộ 3 gem trên, không áp dụng cho searchkick.
3) Tương tác với elasticsearch
Giả sử bạn có các model sau:
Book
id: integer
title: text (search field)
content: text (search field)
author_id: integer
note: text
created_at: datetime
update_at: datetime
Author
id: integer
name: text (search field)
created_at: datetime
update_at: datetime
Step 1: tạo mapping
book . rb
...
# enable elasticsearch on this model
include Elasticsearch :: Model
# set name of index
index_name [ Rails . application . engine_name , Rails . env ]. join ( '_' )
# we use 1 shard for 1 node
settings index: { number_of_shards: 1 } do
# create mapping
mappings do
indexes :title
indexes :content
indexes :authors , type: 'nested' do
indexes :name
end
end
end
# adust data format to index
def as_indexed_json ( options = {})
as_json (
only: [ :title , :content ],
include: { authors: { only: :name } }
)
end
Step 2: index data
Chạy lệnh sau trong rails console
Tạo index
Book . __elasticsearch__ . create_index!
Index data
Book . import
Để rails tự động add, update, delete index của model Book, bạn add dòng lệnh sau vào book.rb
book . rb
...
include Elasticsearch :: Model :: Callbacks
Step 3: tìm kiếm
Tìm kiếm trong rails console
books = Book . search ( 'search text' )
books . class
=> Elasticsearch :: Model :: Response :: Response
Sử dụng kết quả tìm kiếm không thông qua db (nhanh, chỉ có thông tin đã được index trong elasticsearch)
books = Book . search ( 'search text' ). results
book = books [ 0 ]. _source
book . content
Sử dụng kết quả tìm kiếm thông qua db (chậm hơn do phải truy xuất từ db, đầy đủ thông tin)
books = Book . search ( 'search text' ). records
book = books . where ( 'created_at > ?' , 3 . day . ago ). first
book . note
4) Bonus
Bạn có thể overwrite method search mặc định của gem elasticsearch
Ví dụ
book . rb
...
def self . search ( _query )
# create query in json format
query = {
"from" : 0 ,
# only get 5 results
"size" : 5 ,
"query" : {
"bool" : {
"should" : [
{
"multi_match" : {
"query" : _query ,
# title is weighted 5 times more than normal when calculating matching score
"fields" : [ "title^5" , "content" ],
# enable fuzzy match with 1 edit to the original string
"fuzziness" : 1
}
}
]
}
}
}
__elasticsearch__ . search query
end