Text Analysis & Analyzers

Text Analysis (Phân tích văn bản) là quá trình Elasticsearch (thực chất là Lucene) biến đổi văn bản thô (raw text) thành các Tokens (các từ đơn lẻ) để lưu vào Inverted Index.

Nếu không hiểu cơ chế này, bạn sẽ thường xuyên gặp tình huống: "Tại sao tôi lưu 'MacBook Pro' mà tìm 'macbook' lại không ra?" hoặc "Tại sao tôi tìm chính xác cả cụm từ mà nó lại ra kết quả không liên quan?".


1. Quy trình hoạt động của Analyzer

Một Analyzer được cấu thành từ 3 "dây chuyền" xử lý tuần tự:

Character Filters -> Tokenizer -> Token Filters

A. Character Filters (Bộ lọc ký tự) - Tiền xử lý

Nhiệm vụ: Làm sạch chuỗi đầu vào trước khi cắt từ.

  • Ví dụ:

    • HTML Strip Character Filter: Loại bỏ các thẻ HTML (<p>, <div>, &amp;).

    • Mapping Character Filter: Thay thế ký tự (ví dụ: thay :) thành _happy_, hoặc VN thành Vietnam).

B. Tokenizer (Bộ cắt từ) - Cắt chuỗi thành tokens

Nhiệm vụ: Chia văn bản thành các từ (tokens). Đây là bước quan trọng nhất xác định một từ được định nghĩa như thế nào.

  • Standard Tokenizer (Mặc định): Cắt dựa trên khoảng trắng và dấu câu.

    • Input: "Hello, World!" -> Output: [Hello, World]

  • Whitespace Tokenizer: Chỉ cắt dựa trên khoảng trắng.

    • Input: "Hello, World!" -> Output: [Hello,, World!] (Dấu phẩy vẫn dính vào).

  • Keyword Tokenizer: Không cắt gì cả, giữ nguyên toàn bộ input làm 1 token duy nhất (Dùng cho exact match như email, ID).

C. Token Filters (Bộ lọc token) - Hậu xử lý

Nhiệm vụ: Biến đổi các token đã được cắt (thêm, sửa, xóa).

  • Lowercase Filter: Chuyển tất cả về chữ thường (giúp search case-insensitive). [Hello] -> [hello].

  • Stopwords Filter: Loại bỏ các từ vô nghĩa (the, a, an, is, at...). [the, quick, fox] -> [quick, fox].

  • Stemmer Filter: Đưa từ về dạng gốc (ngữ nguyên).

    • Input: running, runs, ran -> Output chung: run.

    • Đây là lý do tìm "run" vẫn ra bài viết chứa "running".

  • ASCII Folding Filter: Chuyển ký tự có dấu thành không dấu (quan trọng cho Tiếng Việt). [café] -> [cafe].


2. Ví dụ Minh Họa (Analyzer tiêu chuẩn hoạt động thế nào?)

Giả sử bạn có câu: "The 2 QUICK Brown-Foxes jumped!"

Khi đi qua Standard Analyzer (Mặc định của ES):

  1. Tokenizer: Cắt theo từ và dấu câu -> [The, 2, QUICK, Brown, Foxes, jumped]

  2. Token Filter (Lowercase): -> [the, 2, quick, brown, foxes, jumped]

  3. Inverted Index lưu: the, 2, quick, brown, foxes, jumped.

Vấn đề: Nếu user tìm fox (số ít), họ sẽ không tìm thấy document này vì trong index chỉ có foxes.

-> Giải pháp: Cần thêm Stemmer Filter (đưa về gốc từ) hoặc Synonym Filter (từ đồng nghĩa).


3. Text Analysis và Tiếng Việt

Tiếng Việt là một ngôn ngữ đơn âm tiết nhưng ghép lại thành từ ghép, nên Standard Analyzer của ES hoạt động rất tệ với Tiếng Việt.

Ví dụ: Từ "Công nghệ thông tin".

  • Standard Analyzer: Cắt thành [công, nghệ, thông, tin].

    • Khi user search "công", nó trả về cả "công nhân", "thành công". (Sai ngữ nghĩa).

    • Nó làm mất tính liên kết của từ ghép.

Giải pháp cho Backend Engineer:

  1. Dùng Plugin icu_tokenizer hoặc vi-analyzer (như elasticsearch-analysis-vietnamese): Các plugin này dùng từ điển để nhận biết "Công nghệ" là một từ, "thông tin" là một từ.

    • Output: [công nghệ, thông tin].

  2. ASCII Folding (Search không dấu):

    • Rất quan trọng để user gõ "hanoi" vẫn tìm ra "Hà Nội".

    • Bạn cần config analyzer có asciifolding filter.


4. Cấu hình Custom Analyzer (Ví dụ thực tế)

Đây là cấu hình mẫu JSON mà bạn thường dùng khi PUT index mới để hỗ trợ tiếng Việt không dấu và tìm kiếm linh hoạt:

JSON

  • Lưu ý: analyzer được dùng lúc Indexing (lưu dữ liệu).

  • Khi Search, mặc định ES sẽ dùng chính analyzer đó để phân tích từ khóa tìm kiếm của user (search_analyzer).


5. Text vs. Keyword (Sự khác biệt cốt tử)

Trong ES, một field String có thể map là text hoặc keyword. Hiểu sai cái này là bug phổ biến nhất.

Loại

Text

Keyword

Analysis

CÓ. Đi qua Analyzer (bị cắt nhỏ, lowercase...).

KHÔNG. Giữ nguyên bản (no-op).

Lưu trữ

Lưu từng token riêng lẻ ([google, engineer]).

Lưu nguyên chuỗi ("Google Engineer").

Query dùng

match (Full-text search).

term (Exact match), aggregation, sorting.

Ví dụ

Nội dung bài viết, mô tả sản phẩm.

Email, ID, Status, Tag, Tên tỉnh thành.

Tip: Mặc định ES Dynamic Mapping sẽ tạo cả hai cho bạn (multi-fields):

  • title: type text (để search full-text).

  • title.keyword: type keyword (để sort hoặc aggregate chính xác).


Last updated