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.
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 đề.
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
index
vàdocument
, 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.
- Ở đây bạn có thể lựa chọn thể loại muốn tìm kiếm
- Search nhanh: Ở đây sẽ trả ra 3 kết quả cho các mục
Tìm kiếm không có hash
- Mặc định sẽ tìm kiếm theo
title
vànội dung
của loại đó. Các nội dung trùng với từ khóa tìm kiếm sẽ đượchighlight
để 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.
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 theoquery
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 theokeywords
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.
- Số lượng bài viết trên Viblo rất là lớn, thêm vào đó còn có
- 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.
- Do dữ liệu không có ràng buộc quan hệ nên việc tìm kiếm theo
- 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:
- Sử dụng Vietnamese Analysis Plugin for Elasticsearch.
- Tính toán để có một con số phù hợp cho trường
fuzziness
. - Đưa ra
type
thích hợp cho độ dài của từ khóa.
-
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.
- Phương án 1: Đánh index khi nội dung được cập nhật
-
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.
- Tìm kiếm riêng từng bảng sau đó sử dụng load để thêm dữ liệu liên quan.
-
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