Cách triển khai Elaticsearch khi phát triển ứng dụng web Rails

Tram Ho

Lưu trữ và tìm kiếm thông tin là hai trong số những công việc quan trọng nhất đối với bất kỳ một ứng dụng web nào. Chúng ảnh hưởng đến thành công của dự án. Một web app phải lưu trữ hàng tỷ bản ghi dữ liệu khác nhau, khiến việc lưu trữ và tìm kiếm của nó trở nên vô cùng khó khăn. Và elasticsearch được sinh ra để giải quyết vấn đề này.
Trong bài viết này, mình sẽ hướng dẫn bạn quá trình tích hợp một app Ruby on Rails đơn giản với Elasticsearch.

Defining the terms

Trước khi bắt tay vào code một web Ruby on Rails và implement thuật toán tìm kiếm chúng ta cùng lướt qua các thuật ngữ chính và cài đặt các service cần thiết.

Elaticsearch là một service tìm kiếm dựa trên dịch vụ tìm kiếm mã nguồn mở JSON-based. Nó cho phép lưu trữ, scan và phân tích dữ liệu cần thiết trong một phần nghìn giây. Service này bao gồm cả việc tích hợp các điều kiên và điều kiện tìm kiếm phức tạp.
Đó là lý do Elaticsearch được yêu thích, chẳng hạn như NASA, Microsoft, eBay, Uber, GitHub, Facebook, Warner Brothers, ….

Chúng ta cùng xem qua một vài thuật ngữ chính của Elasticsearch:

Mapping là một quá trình xác định cách mà các document và các field được lưu trữ và đánh index.

Indexing là một hành động để giữ lại dữ liệu trong elasticsearch, mỗi cluster có thể chứa các index khác nhau mà mỗi index có thể chứa nhiều type. Mỗi type gần giống như 1 table trong database và có 1 danh sách các field được chỉ định cho document của type đó.

Cluster là một tập hợp các node – nơi lưu trữ toàn bộ dữ liệu, thực hiện đánh index và search giữa các node.

Node mỗi node là 1 server bên trong cluster, là nơi lưu trữ dữ liệu, tham gia thực hiện việc đánh index của cluster, và thực hiện search.

Analysis process là một quá trình hiển thị văn bản thành token hoặc term để tìm kiếm.

Analyzer một analyzer bao gồm: character filters, tokenizer, and token filters.

Character filters Trước hết, nó đi qua một hoặc một vài character filters. Nó nhận các field văn bản gốc và sau đó chuyển đổi giá trị bằng cách thêm, xóa hoặc sửa đổi các ký tự. Ví dụ: nó có thể xóa html markup khỏi văn bản.

Tokenizer Sau đó chúng được phân tách thành các token thường sẽ là các từ.

Token filters gần giống như character filters. Sự khác biệt chính là token filters hoạt động với token stream, trong khi character filters hoạt động với character stream.

Inverted index Mục đích của một inverted index là lưu trữ cấu trúc một văn bản cho phép tìm kiếm toàn bộ văn bản một cách nhanh chóng và hiệu quả nhất.

Chúng ta cùng xem ví dụ sau:
Mình có hai câu như sau: “I am a Ruby programmer” và “This project was built in Ruby”.
Vậy trong inverted index, chúng sẽ được lưu như sau:

Nếu chúng ta tìm kiếm với từ khóa “Ruby” chúng ta sẽ thấy là từ khóa được tìm thấy ở trong cả hai câu:

Step #1: Installing the tools

Trước khi bắt đầu với việc code, chúng ta cần cài đặt môi trường và service.

Install Ruby

Install Rails

Install Elasticsearch 6.4.0 Để chắc chắn rằng elasticsearch đã được cài đặt thành công. Bạn hãy truy cập http://localhost:9200/

Chúng ta có thể thấy được một vài cấu hình của elasticsearch:

Install Kibana 6.4.2

Đây là giao diện sử dụng dành cho người dùng trên môi trường web. Kibana sẽ sử dụng Elashtichsearch để tìm kiếm các dữ liệu phù hợp với yêu cầu của người dùng.

Để chắc chắn rằng kibana đã được cài đặt và đang chạy. Bạn hãy truy cập http://localhost:5601/

Step #2: Initiating a new Rails app

Trong ứng dụng lần này chúng ta sẽ sử dụng PostgreSQL cho Rails API:

Config database trong config/database.yml:

Rồi chạy db:create. Chúng ta sẽ tạo Model Location với 2 trường: name và level.

Tiếp theo chúng ta cần fake dữ liệu ban đầu để test cho ứng dụng của bạn trong file db/seeds.rb. Dữ liệu đã được chuẩn bị sẵn tại đây
Đừng quên db:seed để import dữ liệu vào database nhé!

Step #3: Using Elasticsearch with Rails

Để tích hợp được elasticsearch vào ứng dụng chúng ta cần thêm 2 gem sau vào Gemfile:

Đừng quên bundle install để cài đặt nhé!
Bây giờ chúng ta đã sẵn sàng thêm các method, chức năng vào model Location.
Chúng ta tạo file searchable.rb trong app/models/concerns với nội dung sau:

Chúng ta include module Searchable vào trong class Location

Như các bạn thấy trong searchable.rb chúng ta có include 2 module: Elasticsearch::ModelElasticsearch::Model::Callbacks.

– Với Elasticsearch::Modelmô-đun, chúng tôi thêm tích hợp Elaticsearch vào mô hình.

– Với Elasticsearch::Model::Callbacks Mỗi khi một object được lưu, cập nhật hoặc xóa thì dữ liệu được index cũng được cập nhật tương ứng.

Việc tiếp theo chúng ta cần làm là đánh index cho model Location. Mở rails console bằng lệnh rails c và thực thi câu lệnh Location.import force: true.
Để kiểm tra chúng ta sử dụng kibana , truy cập http://localhost:5601/ trên browser và insert GET _cat/indices?v.

Như bạn thấy chúng ta đã tạo index với tên location


Bây giờ chúng ta đã có thể thử nghiệm các câu query với dữ liệu test ban đầu. Bạn cũng có thể tham khảo các câu lệnh Elaticsearch Query DSL tại [đây].(https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html)

Tiếp tục chúng ta cùng insert đoạn code bên dưới:

Các hits attribute được trả về và bạn có thể thấy, tất cả các fields trong Location model đã được index.

Step #4: Building a custom index with autocomplete functionality

Trước khi tạo một index mới chúng ta cần xóa index trước đó. Mở rails console bằng lệnh rails c và thực thi câu lệnh Location.__elasticsearch__.delete_index!, index trước đó sẽ được loại bỏ.

Tiếp đên chúng ta cần thay đổi file app/models/concerns/searchable.rb:

Trong đoạn code trên chúng ta đã serializing các thuộc tính của model thành JSON trong method as_indexed_json. Chúng ta sẽ lấy ra 2 fields: namelevel.

Quan trọng hơn, chúng ta cũng định nghĩa cách cấu hình index.

Mở rails console và kiểm tra các request đã hoạt động đúng hay chưa:

Chúng ta cũng nên kiểm tra các ngoại lệ đã được đặt ra xem chúng hoạt động chính xác chưa nhé!

Step #5: Making the search request available by API

Tiếp tục, chúng ta sẽ tạo HomeController để thực hiện các câu truy vấn.

Thêm mã code vào HomeController:

app/controllers/home_controller.rb:

Cuối cùng, rails s để kiểm tra thành quả. Tới trang http://localhost:3000//home/search?q=new&level=state

Kết quả API trả về sẽ bao gồm những location có name chứa newlevel bằng state.

Như vậy chúng ta đã có một ứng dụng rails được tích hợp chức năng tìm kiếm của elasticsearch.

Advantages and disadvantages

Ưu điểm:

  1. Tốc độ: dùng elasticsearch trả về giá trị rất nhanh, vì chỉ cần tìm kiếm 1 term là trả về các giá trị liên quan tới term đó
  2. Xây dựng trên Lucene: Vì được xây dựng trên Lucene nên Elasticesearch cung cấp khả năng tìm kiếm toàn văn bản (full-text) mạnh mẽ nhất.
  3. Hướng văn bản: Nó lưu trữ các thực thể phức tạp dưới dạng JSON và đánh index tất cả các field theo cách mặc định, do vậy đạt hiệu suất cao hơn.
  4. Giản đồ tự do: Nó lưu trữ số lượng lớn dữ liệu dưới dạng JSON theo cách phân tán. Nó cũng cố gắng phát hiện cấu trúc của dữ liệu và đánh index của dữ liệu hiện tại, làm cho dữ liệu trở nên thân thiện với việc tìm kiếm.

Nhược điểm:

  1. Elasticsearch được thiết kế cho mục đích search, do vậy với những nhiệm vụ khác ngoài search như CRUD (Create Read Update Destroy) thì elasticsearch kém thế hơn so với những database khác như Mongodb, Mysql …. Do vậy người ta ít khi dùng elasticsearch làm database chính, mà thường kết hợp nó với 1 database khác.
  2. Trong elasticsearch không có khái niệm database transaction , tức là nó sẽ không đảm bảo được toàn vẹn dữ liệu trong các hoạt động Insert, Update, Delete.Tức khi chúng ta thực hiện thay đổi nhiều bản ghi nếu xảy ra lỗi thì sẽ làm cho logic của mình bị sai hay dẫn tới mất mát dữ liệu. Đây cũng là 1 phần khiến elasticsearch không nên là database chính.
  3. Không thích hợp với những hệ thống thường xuyên cập nhật dữ liệu. Sẽ rất tốn kém cho việc đánh index dữ liệu.

Trên đây là những tìm hiểu của mình về elasticsearch và việc tích hợp elasticsearch vào một ứng dụng rails đơn giản.

Mong rằng những kiến thức trên sẽ giúp được các bạn trong việc xây dựng ứng dụng của riêng mình

Tài liệu tham khảo:

  1. www.codica.com
Chia sẻ bài viết ngay

Nguồn bài viết : Viblo