Sử dụng Gem Chewy để đánh index và query data trong Ruby on Rails
Bài đăng này đã không được cập nhật trong 7 năm
Như chúng ta đã biết Elasticsearch là một search engine được xây dựng để hoạt động như một server cloud theo cơ chế của RESTful. Elasticsearch phát triển bằng ngôn ngữ Java từ Lucene Apache. ELASTIC-SEARCH có thể tích hợp được với tất cả các ứng dụng sử dụng các loại ngôn ngữ sau:
- Java
- JavaScript
- Groovy
- .NET
- PHP
- Perl
- Python
- Ruby
Chewy là một Gem khá mạnh hỗ trợ việc đánh index và query data với những điểm mạnh sau:
-
Multi-model indexes: Cho phép index ở nhiều model có liên hệ với nhau
-
Every index is observable by all the related models: Tự động reindex khi change trong model và các model có liên hệ
-
Bulk import everywhere: Hỗ trợ việc đánh index với dữ liệu lớn. Có thể đánh index ở bất cứ đâu, công việc cần làm là nhóm những phần tử thay đổi vào cùng một block và đánh index cho chúng cùng một lúc.
-
Powerful querying DSL: Hỗ trợ tối đa các query chainable, mergable and lazy
CÀI ĐẶT
Thêm dòng sau vào trong Gemfile
:
gem 'chewy'
Chạy lệnh sau để cài đặt:
bundle install
Hoặc chạy lệnh sau trong không gian project.
gem install chewy
SETTINGS
Chạy lệnh sau để tạo các file settings cho Chewy:
rails g chewy:install
Setting khi không sử dụng môi trường:
# config/initializers/chewy.rb
Chewy.settings = {host: 'localhost:9250'}
Setting khi sử dụng môi trường:
# config/chewy.yml
# separate environment configs
test:
host: 'localhost:9250'
prefix: 'test'
development:
host: 'localhost:9200'
CÁCH ĐÁNH INDEX CHO MODEL
Để hoàn thành việc đánh index cho model về cơ bản sẽ có những bước sau:
- Tạo file chứa các khai báo index tương ứng với model nằm trong namespace chewy
/app/chewy/users_index.rb
class UsersIndex < Chewy::Index
end
- Thêm một hoặc nhiều kiểu mapping
class UsersIndex < Chewy::Index
define_type User
end
- Khai báo các kiểu đánh index tương ứng cho từng field.
class UsersIndex < Chewy::Index
settings analysis: {
analyzer: {
email: {
tokenizer: 'keyword',
filter: ['lowercase']
}
}
define_type User.active.includes(:country, :badges, :projects) do
field :first_name, :last_name
field :email, analyzer: 'email'
field :projects do
field :title
field :description
end
field :rating, type: 'integer'
end
- Tự động đánh index cho những bản ghi thay đổi trong model
class User < ActiveRecord::Base
update_index('users#user') { self }
end
Ngoài ra có thể thay đổi cài đặt mặc định khi đánh index bằng options sau
define_type User do
default_import_options batch_size: 100, bulk_size: 10.megabytes, refresh: false
field :name
end
Đánh index với khai báo nested
define_type User do
field :projects do
field :title
field :description
end
end
CÁC LỆNH CƠ BẢN CỦA INDEX MODEL
Lấy ra các type của index model
UsersIndex::User # => UsersIndex::User
UsersIndex.type_hash['user'] # => UsersIndex::User
UsersIndex.type('user') # => UsersIndex::User
UsersIndex.type('foo') # => raises error UndefinedType("Unknown type in UsersIndex: foo")
UsersIndex.types # => [UsersIndex::User]
UsersIndex.type_names # => ['user']
Các toán tử có thể dùng cho model index
UsersIndex.delete # Xóa index nếu nó tồn tại
UsersIndex.delete!
UsersIndex.create
UsersIndex.create! # Tạo index
UsersIndex.purge
UsersIndex.purge! # Xóa index sau khi tạo
UsersIndex::User.import # Thêm index với 0 điều kiện sẽ mặc định cho tất cả data hiện có
UsersIndex::User.import User.where('rating > 100') # Impot index với điều kiện
UsersIndex.import # Import với tất cả các type
UsersIndex.import user: User.where('rating > 100') # Import với điều kiện
UsersIndex.reset! # Reset lại index
Đánh index với điều kiện
define_type User, delete_if: :deleted_at
define_type User, delete_if: -> { deleted_at }
define_type User, delete_if: ->(user) { user.deleted_at }
INDEX QUERY VÀ FILTERS QUERY
Chewy cung cấp những câu query khá tiện ích và mềm dẻo. Ví dụ:
scope = UsersIndex.query(term: {name: 'foo'})
.filter(range: {rating: {gte: 100}})
.order(created: :desc)
.limit(20).offset(100)
scope.to_a # => Đổi kết quả về dạng mảng
scope.map { |user| user.email }
scope.total_count # => Trả về tổng số lượng records
scope.per(10).page(3) # Kết hợp với kaminari để phân trang
scope.explain.map { |user| user._explanation }
scope.only(:id, :email) # Trả về object với hai attributes id và email
scope.merge(other_scope) # Thêm điều kiện với một scope khác.
Một số câu lệnh xóa
UsersIndex.delete_all
UsersIndex::User.delete_all
UsersIndex.filter{ age < 42 }.delete_all
UsersIndex::User.filter{ age < 42 }.delete_all
Một số cách filters đơn giản
UsersIndex.filter{ name == 'Fred' }
UsersIndex.filter{ age <= 42 }
UsersIndex.filter{ s('doc["num"] > 1') }
UsersIndex.filter{ q(query_string: {query: 'lazy fox'}) }
UsersIndex.filter{ ~name == 'Name' }
UsersIndex.filter{ ~(name == 'Name') }
UsersIndex.filter{ ~(age > 42) & (age <= 50) }
UsersIndex.filter{ name(cache: true) == 'Name' }
UsersIndex.filter{ name(cache: false) == 'Name' }
UsersIndex.filter{ name(cache: 'name_regexp') =~ /Name/ }
UsersIndex.filter{ name(cache: true) =~ /Name/ }
KẾT LUẬN
Trên đây mình chỉ giới thiệu những cài đặt cơ bản và dễ sử dụng của Chewy
nhưng sức mạnh của Chewy
không chỉ dừng lại ở đó. Để tìm hiểu sâu hơn về nó các bạn có thể tìm hiểu ở Đây
Thanks you for reading !!!
All rights reserved