Sử dụng Gem Chewy để đánh index và query data trong Ruby on Rails
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 ...
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
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
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'
Để 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
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 }
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/ }
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 !!!