1. Giới thiệu
Chi phí liên quan đến n-gram tokenizer ở ElasticSearch và opensearch thường không đề cập chi tiết trong các tài liệu, do đó, có khi nó sẽ gây ra các hậu quả khá nghiêm trọng về chi phí và hiệu năng. Dẫn đến trường hợp là chúng ta phải “lấy thịt đè người” bằng cách tăng chi phí phần cứng một cách lãng phí. Trong bài viết này, chúng ta sẽ đề cập đến vài use-case sử dụng n-gram tokenizer, một số phương pháp cải tiến, hoặc một vài phương pháp thay thế nó bằng cách khách hiệu quả hơn.
Ngày nay, Elasticsearch và OpenSearch là hai engines được nhiều công ty sử dụng để làm tìm kiếm văn bản nội bộ, làm bộ máy tìm kiếm chính để sử dụng nội bộ hoặc cung cấp dịch vụ cho khách hàng bên ngoài.
Hầu hết các lập trình viên sẽ sử dụng hàm analyzers và tokenizers mặc định do Elasticsearch và OpenSearch cung cấp sẵn, để chia nhỏ đoạn văn bản thành các token. Ví dụ như câu “Đây là năm rất lạ lùng” khi sử dụng analyzer mặc định thì sẽ chia thành danh sách các từ [ Đây, là, năm, rất, lạ, lùng], mỗi từ trong danh sách các từ trên đều có thể dễ dàng được search. Đây là cái mà chúng ta thường gọi là “full-text-search”, là tìm kiếm văn bản bằng dựa trên một hoặc một vài từ có tồn tại trong đoạn văn bản đó.
Trong một số trường hợp hợp, người ta sẽ sử dụng các analyzer đặc biệt để làm các công việc đặc biệt, không phải là full text search.
Một trong những thành phần đặc biệt trong elasticsearch và open search là n-gram tokenizer. Hãy điểm qua một vài ứng dụng của nó mà người cấu hình thường hay sử dụng sai
N-gram Tokenizer
N-gram Tokenizer tạo ra một nhóm các ký tự, những token nó tạo ra không nhất thiết là những từ giống như analyzer tiêu chuẩn, nó chứa những từ liên tiên tiếp nhau, chiều dài của token phụ thuộc vào N. Ví dụ trong trường hợp N = 2 và từ của cúng ta là “lạ lùng”, chúng ta có các token là [l, lạ, ạ, “ạ “, " “, " l”, l, lù, ù, ùn, n, ng, g]
Bạn có thể thấy rằng, thay vì chỉ tạo ra hai token [lạ, lùng], n-gram sẽ chia dữ liệu thành nhóm các ký tự. Phụ thuộc vào N mà ta có số lượng token khác nhau, Trong ví dụ trên, chúng ta có 17 token với N = 2 , nghĩa là số lượng token đã tăng hơn 6 lần. Trong trường hợp N=3, N=4, hoặc trong trường hợp từ cần index dài hơn, số lượng token còn bị nhân lên gấp nhiều lần nữa
Sử dụng N-gram trong trường hợp tìm kiếm
Có rất nhiều tư vấn trên mạng về cách sử dụng n-gram, và các tư vấn trên thường xoay quanh các chủ đề sau
- Phát hiện lỗi chính tả
Việc gõ văn bản sai chính tả là một vấn đề thường gặp, ngay cả các báo chí chính thống cũng gặp trường hợp trên. Ví dụ người dùng có thể gõ sai từ “apple” thành “aple” (điện thoại apple). Việc sử dụng n-grams sẽ giúp ta giải phát hiện từ bị gõ sai, trong khi đó, analyzer mặc định sẽ không phát hiện ra.
- Tìm kiếm trong lúc gõ
Thực hiện việc search trong lúc người dùng gõ trên thanh tìm kiếm. Nó sẽ tìm kiếm trước các kết quả hợp lệ ngay cả khi người dùng chưa hoàn tất việc tìm kiếm. Ví dụ gợi ý từ khoá “iphone 14 promax” khi người dùng chỉ mới gõ đến từ “ipho”
- Prefix searches
Tìm kiếm văn bản bắt đầu của từ, ví dụ người dùng gõ “ip” thì sẽ khớp với “iphone”, khi từ “ip” được index là token của từ “iphone”. Prefix search chỉ lấy index, không thực hiện prefix query
- Suffix searches
Đối lập với Prefix searches, đôi lúc chúng ta sẽ cần tìm kiếm các ký tự ở cuối, ví dụ như biển số xe (thường người dùng sẽ không nhớ phần ký hiệu và ký số đầu, ví dụ 50A1), số điện thoại ( tìm kiếm 4 ký tự cuối).
- Infix searches
Tương tự như trên, nhưng tìm ở giữa.
Trong những trường hợp trên, lập trình viên hay được tư vấn là xài n-gram. N-gram có thể giải quyết các vấn đề trên, nhưng chúng ta có thể sử dụng nhiều các khác hiệu quả hơn.
Lý do không nên xài n-gram là vì sự bùng nổ token do chính n-gram mang lại, dẫn đến chúng ta cần tiêu tốn nhiều tài nguyên như CPU, RAM để xử lý index, tạo token trong lúc index và search, tốn nhiều ổ cứng để lưu trữ. Cuối cùng, hiệu năng truy vấn sẽ giảm.
Thay thế n-gram
Chúng ta sẽ xem xét từng trường hợp cụ thể
- Gõ sai chính tả
Thay vì sử dụng n-gram, chúng ta có thể sử dụng term suggester và phrase suggester trong elastic search, link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html#phrase-suggester, https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html#term-suggester, đơn giản.
- Tìm kiếm trong lúc gõ
Cái này thì chúng ta xài n-gram cũng được, nhưng mà elastic search có hỗ trợ cho chúng ta một vài tiện ích đơn giản hơn nhiều, chúng ta không cần phải vắt óc suy nghĩ cấu hình n bằng bao nhiêu. Đó là sử dụng trường dữ liệu search-as-you-type https://www.elastic.co/guide/en/elasticsearch/reference/current/search-as-you-type.html. Hoặc chúng ta có thể sử dụng completion suggester và context suggester, link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html#completion-suggester , https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html#context-suggester
- Prefix searches
Elastic cũng hỗ trợ sẵn luôn, đó là Prefix queryedit https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-prefix-query.html
- Suffix searches
Chỗ này chúng ta sẽ sử dụng combo Reverse token filter và Match phrase prefix query https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-reverse-tokenfilter.html, https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase-prefix.html#query-dsl-match-query-phrase-prefix
Ví dụ như chúng ta có số điện thoại 0902987235, chúng ta sẽ Reverse token filter thành 5327892090, 4 số cuối cần tìm là 7235 sẽ bị reverser thành 5327, thực hiện Match phrase prefix query 5327, chúng ta sẽ tìm được 5327892090 , Reverse lại ra chuỗi số điện thoại cần tìm.
- Infix searches
Đây là ông tốn nhiều chi phí nhất, với sql engine, chúng ta xài từ khoá like dẫn đến bị mất index, với n-gram, chúng ta phải index hết toàn bộ token, vào. Trong elastic có hỗ trợ chúng ta Word delimiter graph token filter, giải quyết cái này dễ dàng https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-word-delimiter-graph-tokenfilter.html
Kết luận
Với các công nghệ trên, chúng sẽ giúp chúng ta nhàn hơn khi sử dụng elastic, opensearch. Các bạn nếu có đang bị những vướng mắc trên, hãy thử các cách được đề xuất, biết đâu bất ngờ sẽ xảy ra.
Nguồn: https://blog.bigdataboutique.com/2023/01/dont-use-n-gram-in-elasticsearch-and-opensearch-6f0b48
Cảm ơn các bạn đã theo dõi bài viết, hẹn gặp lại ở các bài viết tiếp theo
Comments