+3

Elasticsearch là gì? áp dụng elasticsearch vào dự án laravel như thế nào

Mở đầu

Xin chào các bạn hôm nay mình sẽ giới thiệu đến mọi người về Elasticsearch cách ứng dụng nó vào dự án thực tế, và các lưu ý khi sử dụng Elasticsearch là gì, cùng bắt đầu luôn nhé 😄

Elasticsearch là gì

Elasticsearch là một công cụ tìm kiếm và phân tích dữ liệu phân tán, dựa trên mã nguồn mở Apache Lucene. Nó được phát triển bởi Elasticsearch BV và được thiết kế để giải quyết các vấn đề về tìm kiếm, phân tích và lưu trữ dữ liệu có tính sẵn sàng cao và khả năng mở rộng lớn.

  • Có khả năng mở rộng cao, xử lý lượng lớn dữ liệu
  • Đảm bảo tìm kiếm nhanh ngay cả với số lượng lớn document
  • Được sử dụng rộng rãi trong các hệ thống lớn về tìm kiếm và phân tích dữ liệu

image.png

Lịch sử và phát triển của Elasticsearch

Elasticsearch được phát triển lần đầu tiên vào năm 2010 bởi Shay Banon. Elasticsearch nhanh chóng trở nên phổ biến trong cộng đồng mã nguồn mở và được áp dụng rộng rãi trong nhiều lĩnh vực như tìm kiếm trên trang web, phân tích dữ liệu, giám sát và quản lý nhật ký. Nó đã trở thành một trong những công cụ tìm kiếm phân tán hàng đầu trên thị trường. Hiện nay, Elasticsearch là một phần của Elastic Stack (trước đây là ELK Stack), bao gồm Kibana (giao diện hiển thị dữ liệu).

Các khái niệm cơ bản trong Elasticsearch

Node: Một node (nút) là một thực thể đơn lẻ trong cụm Elasticsearch. Nó có thể là một máy vật lý hoặc một máy ảo và lưu trữ một phần dữ liệu của cụm.

Cluster: Một cluster (cụm) là một tập hợp của một hoặc nhiều node, bao gồm dữ liệu và cung cấp các dịch vụ tìm kiếm, lập chỉ mục và phân tích. Cluster giúp tăng khả năng mở rộng, tính sẵn sàng và tính năng của Elasticsearch.

Index: Một index (chỉ mục) là một tập hợp các document (tài liệu) có cấu trúc tương tự. Nó giống như một database trong các hệ thống quản lý cơ sở dữ liệu quan hệ truyền thống.

Document: Một document là một đơn vị dữ liệu cơ bản trong Elasticsearch, tương tự như một hàng trong một bảng trong cơ sở dữ liệu quan hệ. Mỗi document được lưu trữ trong một index nhất định.

Shards: Một index trong Elasticsearch có thể được chia nhỏ thành nhiều phân đoạn (shards) để phân tán trên nhiều node. Điều này giúp tăng khả năng mở rộng và hiệu suất.

Replicas: Replicas (bản sao) là bản sao của một shard. Chúng được sử dụng để đảm bảo tính sẵn sàng cao và khả năng phục hồi dữ liệu trong trường hợp xảy ra lỗi hoặc sự cố.

Cách hoạt động của Elasticsearch

Elasticsearch là một công cụ tìm kiếm phân tán và mạnh mẽ, được thiết kế để xử lý hiệu quả các truy vấn phức tạp trên khối lượng dữ liệu lớn. Để hiểu hơn về cách hoạt động của Elasticsearch, chúng ta sẽ tìm hiểu về quá trình lưu trữ, tìm kiếm dữ liệu và cách xử lý các truy vấn.

  • Lưu trữ dữ liệu : Elasticsearch lưu trữ dữ liệu dưới dạng các tài liệu JSON. Mỗi tài liệu đều có một loại và thuộc về một chỉ mục. Chỉ mục trong Elasticsearch tương tự như cơ sở dữ liệu trong SQL. Mỗi chỉ mục bao gồm một hoặc nhiều shard, mỗi shard là một đơn vị độc lập có thể được lưu trữ trên bất kỳ nút nào trong cụm.

  • Tìm kiếm dữ liệu: Elasticsearch sử dụng cấu trúc dữ liệu gọi là inverted index để tìm kiếm dữ liệu. Inverted index là một cấu trúc dữ liệu giúp tìm kiếm dữ liệu một cách nhanh chóng. Khi một truy vấn được thực hiện, Elasticsearch sẽ tìm kiếm trong Inverted index để tìm các tài liệu phù hợp. Elasticsearch sử dụng các thuật toán xếp hạng phức tạp, như TF-IDF (Term Frequency - Inverse Document Frequency), để xác định mức độ phù hợp của mỗi document với truy vấn. Các kết quả tìm kiếm từ tất cả các shard sẽ được tổng hợp lại và xếp hạng dựa trên mức độ phù hợp này.

  • Xử lý truy vấn phức tạp : Elasticsearch xử lý các truy vấn phức tạp bằng cách sử dụng DSL (Domain Specific Language) dựa trên JSON. DSL cho phép bạn xây dựng các truy vấn phức tạp như truy vấn lồng nhau, truy vấn kết hợp, và truy vấn dựa trên khoảng cách. Elasticsearch cũng hỗ trợ các tính năng phân tích như bucketing, sorting, và filtering để giúp bạn phân tích dữ liệu của mình.

Tích hợp Elasticsearch với Laravel sử dụng Laravel Scout

Laravel Scout

Laravel Scout là một gói cung cấp chức năng tìm kiếm và indexing cho các model trong Laravel. Từ Laravel 5.3 trở đi Laravel Scout đã được tích hợp khi cài đặt laravel mới. Laravel Scout hỗ trợ nhiều driver tìm kiếm khác nhau, trong đó có Elasticsearch. image.png

Cấu hình và cài đặt Laravel Scout với Elasticsearch Driver

Để tích hợp Elasticsearch với Laravel Scout, bạn cần cài đặt gói laravel/scout và scouts/elastic-scout-driver thông qua Composer. Sau đó, cấu hình Scout để sử dụng Elasticsearch Driver trong file config/scout.php:

driver: Trường này xác định trình tìm kiếm mà Laravel Scout sử dụng.

prefix: Trường này xác định một tiền tố (prefix) cho các chỉ mục Elasticsearch.

queue: Trường này xác định xem việc đánh index và deindex nên được đặt trong hàng đợi (queue) hay không.

chunk: Trường này xác định số lượng tài liệu cần được xử lý trong mỗi lượt khi đánh index hoặc deindex.

soft_delete: Trường này xác định xem bạn có sử dụng tính năng "soft delete" trong Laravel hay không.

Xây dựng mô hình Searchable và Index dữ liệu vào Elasticsearch

Để làm cho một mô hình có thể tìm kiếm được, bạn cần thực thi trait Laravel\Scout\Searchable trong mô hình đó. Ví dụ, với mô hình Post:

<?php

namespace App\Models;

use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use Searchable;

    // ...
}

Sau đó, bạn có thể sử dụng lệnh scout:import để lập chỉ mục tất cả các bản ghi hiện có trong Elasticsearch:

php artisan scout:import "App\Models\Post"

Khi có thay đổi dữ liệu, index sẽ tự động được cập nhật:

  • Tạo mới model: dữ liệu sẽ được thêm vào index
  • Cập nhật model: dữ liệu trong index sẽ được update
  • Xóa model: dữ liệu sẽ bị xóa khỏi index

Như vậy là Laravel Scout đã giúp đơn giản hóa việc đánh index dữ liệu lên Elasticsearch thông qua các driver tương ứng.

Index dữ liệu từ các bảng liên kết

Khi muốn thực hiện tìm kiếm trên các mối quan hệ (relations) trong Laravel và đánh index dữ liệu từ các mối quan hệ này trong Elasticsearch, Cần định nghĩa trường tìm kiếm mới để lưu trữ thông tin liên quan. Trường này sẽ được đánh index cùng với dữ liệu của model gốc

  • Mặc định toSearchableArray() sẽ trả về tất cả attributes của model.
  • Có thể customize lại để loại bỏ hoặc thêm các trường muốn index.
  • Có thể biến đổi dữ liệu trước khi index, vd: text formatting, datetime formatting, lấy data từ relation.

Một số lưu ý khi đánh index dữ liệu:

  • Nên đánh index trên các trường dữ liệu được sử dụng để tìm kiếm, lọc như tiêu đề, nội dung, tags, danh mục, ngày tạo... Không cần thiết phải index toàn bộ các trường.
  • Trường id của model thường không cần đánh index vì Elasticsearch tự sinh id riêng. Nên để _id là primary key trong Elasticsearch.
  • Các trường có nhiều giá trị null hoặc rỗng thì không nên đánh index sẽ lãng phí dung lượng.
  • Đối với những trường text lớn, nên đánh index theo kiểu text thay vì keyword để tăng khả năng tìm kiếm full-text.
  • Chỉ định cụ thể những trường nào được index và kiểu index như thế nào.
  • Không nên đánh index những dữ liệu nhạy cảm về bảo mật.

Thực hiện các truy vấn tìm kiếm đơn giản và phức tạp

Scout cung cấp các phương thức đơn giản để thực hiện truy vấn tìm kiếm trong Elasticsearch. Ví dụ, để tìm kiếm các bài viết có tiêu đề hoặc nội dung chứa từ khóa "laravel":

$posts = App\Models\Post::search('laravel')->get();

Bạn cũng có thể thực hiện các truy vấn phức tạp hơn bằng cách sử dụng các phương thức như where, whereIn, whereNotIn, whereBetween...

$posts = App\Models\Post::search('laravel')
    ->where('published_at', '>=', Carbon::today()->subDay())
    ->whereIn('category_id', [1, 2, 3])
    ->orderBy('created_at', 'desc')
    ->get();

Ngoài ra, Laravel Scout cũng cho phép bạn xây dựng các truy vấn Bool Query phức tạp, một loại truy vấn mạnh mẽ của Elasticsearch cho phép kết hợp nhiều điều kiện lọc và tìm kiếm khác nhau. Bool Query sử dụng các toán tử logic như must, should, must_not, và filter để kết hợp các truy vấn con.

image1.png

Cú pháp đầy đủ của 1 bool query:

  • must: Các điều kiện BẮT BUỘC phải đúng. Tương đương AND.
  • filter: Các điều kiện lọc, chỉ có giá trị đúng/sai
  • should: Các điều kiện TÙY CHỌN, chỉ cần 1 điều kiện đúng là được. Tương đương OR.
  • must_not: Các điều kiện PHỦ ĐỊNH, không được đúng. Tương đương NOT.
  • minimum_should_match: Số lượng ít nhất các điều kiện should cần phải đúng.
  • boost: Hệ số điểm boost cho cả bool query.

Ngoài tìm kiếm từ khóa trên 1 trường thì còn có thể tìm kiếm trên nhiều trường cùng 1 lúc

  • query: từ khóa cần tìm kiếm.
  • fields: danh sách các trường dữ liệu cần tìm kiếm
  • operator: đặt toán tử dùng để nối các điều kiện tìm kiếm trong fields.
  • minimum_should_match:chỉ định số lượng tối thiểu các điều kiện "should" trong truy vấn multi_match cần phải được đáp ứng hoặc tỷ lệ phần trăm tương ứng.
  • max_expansions: xác định số lần mở rộng tối đa cho từ khoá tìm kiếm
  • fuzziness: Trường này đặt giá trị cho tính năng fuzzy search (tìm kiếm gần đúng).
  • type: xác định loại truy vấn.

image3.png

Bool Query mạnh mẽ hơn nhiều so với việc chỉ sử dụng các phương thức where đơn giản. Nó cho phép bạn tạo ra các truy vấn phức tạp bằng cách kết hợp nhiều điều kiện khác nhau, mở rộng khả năng tìm kiếm và lọc dữ liệu của ứng dụng Laravel.

Tóm lại, Laravel Scout cung cấp một cách đơn giản và linh hoạt để thực hiện các truy vấn phức tạp trong Elasticsearch, từ việc sử dụng các phương thức where đơn giản đến việc xây dựng các Bool Query phức tạp kết hợp nhiều điều kiện khác nhau.

Kết Luận

Trong bài viết này,mình đã giới thiệu về Elasticsearch và cách tích hợp nó vào ứng dụng Laravel thông qua Laravel Scout. Elasticsearch là một công cụ tìm kiếm và phân tích dữ liệu mạnh mẽ, có khả năng xử lý hàng triệu document và thực hiện các truy vấn tìm kiếm nhanh chóng và hiệu quả. Laravel Scout, một phần của framework Laravel, cung cấp một cách dễ dàng để tích hợp Elasticsearch vào các dự án Laravel của bạn mà không cần nhiều công sức.

Ngoài ra, còn một số lưu ý quan trọng khi sử dụng Elasticsearch trên production:

  • Thêm prefix cho index name
  • Thêm middleware điều tiết tốc độ truy cập (throttle):
    • Giúp ngăn chặn các cuộc tấn công DDOS gây quá tải cho Elasticsearch.
    • Có thể điều chỉnh giới hạn số lượng request/giây cho phù hợp.
  • Ước tính tài nguyên cần thiết:
  • Bảo Mật:
    • Cài đặt bảo mật cho Elasticsearch để đảm bảo chỉ có người dùng có quyền mới có thể truy cập và thao tác với dữ liệu của bạn. Sử dụng cơ chế xác thực và kiểm tra quyền truy cập.
  • Sao Lưu Dữ Liệu:
  • Thực Hiện Tối Ưu Hóa:
    • Liên tục thực hiện tối ưu hóa chỉ mục và truy vấn để cải thiện hiệu suất và sẵn sàng.
    • Lập Kế Hoạch Mở Rộng:

Có thắc mắc hay góp ý cho bài viết các ban hãy comment xuống bên dưới nhé, nếu thấy bài viết hữu ích hãy cho mình 1 upvote nhé, cảm ơn các bạn 😄


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.