+12

Sử dụng Elasticsearch hỗ trợ tìm kiếm trên Viblo

Bối cảnh

Với một nền tảng blog như Viblo, việc tìm kiếm thông tin trong bài viết là vô cùng cần thiết và thuận tiện cho người dùng. Thêm vào đó, mô hình tìm kiếm cũ đã không còn phù hợp với số lượng bài viết hiện tại, làm cho tốc độ tìm kiếm tăng lên đáng kể, kết quả thiếu độ chính xác.

Tiếp đó là việc tìm kiếm dựa trên tính năng SEO của Viblo trên Google cũng khó có thể đưa ra được nội dung chính xác vì phần mô tả bị giới hạn, làm cho mà người dùng có thể không tiếp cận được nội dung.

image.png

Tính năng SEO trên Viblo.

Chính vì vậy, đội phát triển của Viblo quyết định thay đổi tính năng tìm kiếm cũ bằng một công cụ tìm kiếm mới, nhằm nâng cao việc tìm kiếm trên Viblo để phù hợp với lượng dữ liệu đang gia tăng hàng ngày.

Bài toán được đưa ra vào thời điểm đó là:

  • Làm sao để người dùng tìm kiếm nội dung một cách thuận lợi nhất?
  • Phân chia nội dung như thế nào?
  • Các tiêu chí tìm kiếm là gì?
  • Sắp xếp kết quả ra sao?
  • Giảm thời gian của việc tìm kiếm như thế nào?
  • ...

Và sau quá trình thảo luận, Elasticsearch - công cụ tìm kiếm mạnh mẽ tại thời điểm đó, đã được lựa chọn để giải quyết vấn đề.

image.png

Tính năng search trên Viblo.

Sơ lược về Elasticsearch

  • Elasticsearch là một hệ thống tìm kiếm phân tán mã nguồn mở, với khả năng phân tích dữ liệu mạnh mẽ và được xây dựng trên nền tảng Apache Lucene.

  • Dữ liệu trong Elasticsearch được tổ chức thành các indexdocument, từ đó tạo nên mô hình linh hoạt và dễ mở rộng. Hệ thống này sử dụng giao thức HTTP và cung cấp một API RESTful, giúp kết nối và tương tác dễ dàng từ bất kỳ ngôn ngữ lập trình nào hỗ trợ HTTP.

  • Elasticsearch không chỉ là công cụ tìm kiếm, mà còn làm phong phú dữ liệu với khả năng phân tích ngôn ngữ tự nhiên, tìm kiếm full-text và hỗ trợ thời gian thực.

  • Ngoài ra Elasticsearch còn được tích hợp Logstash và Kibana, giúp nó trở thành một phần quan trọng của ELK stack (Elasticsearch, Logstash, Kibana), giúp tổ chức nhanh chóng đối mặt với thách thức của việc quản lý và tìm kiếm dữ liệu lớn.

Ưu điểm

  • Là phần mềm mã nguồn mở, hoàn toàn miễn phí, cộng đồng phát triển lớn.
  • Tốc độ nhanh, có khả năng thực hiện những câu truy vấn phức tập một cách nhanh chóng.
  • Hỗ trợ Full-text search: với các tính năng như tách từ, tách câu, tạo chỉ mục cho dữ liệu.
  • Hỗ trợ Restful API.
  • Dữ liệu được lưu dưới dạng document oriented, free schema nên rất linh hoạt trong việc dữ liệu thường xuyên thay đổi.
  • Khả năng mở rộng và tính sẵn dùng cao.

Nhược điểm

  • Không phù hợp cho những trường hợp mà dữ liệu được ghi nhiều (CRUD - thêm, sửa, xóa).
  • Không hỗ trợ transaction, không có ràng buộc quan hệ giữa các dữ liệu dẫn tới việc dữ liệu có thể bị sai.

Tại sao lại là Elasticsearch?

Tiêu Chí Elasticsearch PostgreSQL với Trigram Index
Phân Tích Dữ Liệu Hệ thống tìm kiếm và phân tích mạnh mẽ, hỗ trợ đa dạng tính năng phân tích Hỗ trợ tìm kiếm gần đúng thông qua Trigram Index, có tính năng SQL phong phú
Tính Năng Phân Tích Phân tích ngôn ngữ tự nhiên, đồ họa thống kê Tìm kiếm gần đúng qua Trigram Index, tính năng SQL
Tích Hợp Dữ Liệu Hỗ trợ cả dữ liệu có cấu trúc và không có cấu trúc Dành cho cơ sở dữ liệu có cấu trúc, dữ liệu text
Hiệu Suất Tìm Kiếm Hiệu suất cao, đặc biệt là cho tìm kiếm full-text Hiệu suất tốt, đặc biệt là cho tìm kiếm gần đúng
Khả Năng Mở Rộng Có khả năng mở rộng ngang mạnh mẽ Cần cẩn thận khi mở rộng

Quá trình ứng dụng vào dự án

Yêu cầu và giải pháp

1. Yêu cầu

  • Tìm kiếm theo title, nội dung, tag, user, nội dung trong code.
  • Tìm kiếm nhanh theo tất cả nội dung.
  • Tìm kiếm theo từng tiêu chí.

2. Giải pháp

  • Gắn thêm hash: title, body, code, tag, user vào trước nội dung cần tìm kiếm để phân chia.
    • Ưu điểm: tập trung vào 1 tiêu chí nhất định.
    • Nhược điểm: người dùng phải tự phán đoán nội dung tìm kiếm thuộc tiêu chí nào.
  • Phân chia loại tìm kiếm theo bài viết, câu hỏi, tác giả.
    • Ưu điểm: tránh được việc nội dung bị lộn xộn, người dùng có thể biết được nội dung tìm kiếm thuộc loại nào.

Cơ chế hoạt động

  • Có 2 loại search ở Viblo:

    • Search nhanh: Ở đây sẽ trả ra 3 kết quả cho các mục bài viết, câu hỏi, tác giả, tag

    Ví dụ: Tìm kiếm nhanh trên Viblo.

    • Search nâng cao: để sử dụng bạn có thể click vào biểu tượng kính lúp trên ô tìm kiếm hoặc truy cập bằng đường dẫn /search
      • Ở đây bạn có thể lựa chọn thể loại muốn tìm kiếm bài viết, câu hỏi, tác giả.
      • Cùng với các format tìm kiếm title, body, code, tag, user giúp người dùng thuận tiện hơn.
      • Kết quả tìm kiếm cũng có thể được sắp xếp theo các tiêu chí phù hợp nhất, lượt bookmark, view, vote, mới, cũ để tìm kiếm một cách hiệu quả hơn.

image.png

Ví dụ: Tìm kiếm nâng cao.

Tìm kiếm không có hash

  • Mặc định sẽ tìm kiếm theo titlenội dung của loại đó. Các nội dung trùng với từ khóa tìm kiếm sẽ được highlight để người dùng dễ dàng chọn lọc và người dùng có thể sắp xếp kết quả theo các tiêu chí (dưới nút tìm kiếm) để tìm được kết quả chất lượng nhất.

image.png

Ví dụ: Kết quả tìm kiếm không có hash.

Tìm kiếm có hash

  • Đầu tiên hash sẽ được cắt ra và phân biệt mục tiêu cần tìm kiếm.

  • Tiếp theo dựa theo hash để gọi tới query phù hợp đã được định nghĩa dựa theo query của Elasticsearch.

  • Tham khảo cách viết Query Elasticsearch

    Ví dụ: query Elasticsearch tìm kiếm nội dung trong bài viết

    $keywords = 'Elasticsearch trong Viblo'
    $field = 'body';
    [
        'bool' => [
            'must' => [
                'multi_match' => [
                    'query' => $keywords,
                    'fields' => [$field],
                    'minimum_should_match' => '3<90%',
                    'fuzziness' => 'AUTO',
                    'type' => 'best_fields',
                ]
            ]
        ]
    ]
    
  • Sau khi kết quả tìm kiếm được trả ra, chúng sẽ được highlight dựa theo keywords của người dùng cuối cùng trả ra về và hiển thị lên trang web cho người dùng.

fuzziness: tùy theo độ dài của keywords mà có thể đưa ra một con số phù hợp

minimum_should_match: tùy theo yêu cầu mà định ra một con số phù hợp

Khó khăn trong quá trình ứng dụng

  • Xử lý tìm kiếm từ khóa Tiếng Việt.
  • Xử lý dữ liệu các bài viết, câu hỏi được update:
    • Số lượng bài viết trên Viblo rất là lớn, thêm vào đó còn có tag, user nên khi đánh index sẽ rất tốn thời gian.
  • Tìm kiếm dữ liệu giữa nhiều bảng:
    • Do dữ liệu không có ràng buộc quan hệ nên việc tìm kiếm theo hash gặp khó khăn khi liên kết giữa các bảng.
  • Vấn đề bảo mật: XSS, SQL injection,...

Giải pháp giải quyết các vấn đề

  • Xử lý tìm kiếm từ khóa Tiếng Việt:

  • Xử lý dữ liệu các bài viết, câu hỏi được update:

    • Phương án 1: Đánh index khi nội dung được cập nhật
      • Ưu điểm: Nội dung được cập nhật theo thời gian thực.
      • Nhược điểm: Dễ dẫn đến sai sót dữ liệu trong Elasticsearch.
    • Phương án 2: Chạy scheduling để đánh lại index cho nội dung.
      • Ưu điểm: Tránh việc sai sót dữ liệu.
      • Nhược điểm: Nội dung mới sẽ không thể được tìm kiếm ngay lập tức.

    Cuối cùng chúng tôi đã quyết định kết hợp cả 2 phương pháp để nội dung được cập nhật nhanh chóng và giảm sai sót nội dung trong Elasticsearch.

  • Tìm kiếm dữ liệu giữa nhiều bảng:

    • Tìm kiếm riêng từng bảng sau đó sử dụng load để thêm dữ liệu liên quan.
      • Ưu điểm: Nội dung tìm kiếm được sắp xếp chất lượng hơn do có nhiều tiêu chí tìm kiếm.
      • Nhược điểm: Số lượng nội dung lớn, người dùng có thể bị mất thông tin do phân trang.
  • Vấn đề bảo mật:

    • Validate dữ liệu của người dùng truyền vào để loại bỏ việc câu lệnh được thực thi.

Kết luận

Chúng tôi mong rằng việc nâng cấp tính năng sẽ mang đến sự thuận tiện cho người dùng trong việc tìm kiếm nội dung cần thiết. Trong thời gian tới, chúng tôi vẫn sẽ cố gắng để cải thiện các vấn đề đang tồn tại và tiếp tục phát triển sản phẩm, đưa ra những nội dung có chất lượng đến với người dùng.


©️ Tác giả: Software Engineer Giang Nguyen


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí