Elasticsearch thực chiến cho backend
Sê-ri nâng cao về Elasticsearch cho lập trình viên backend: inverted index, phân tích văn bản, truy vấn, relevance, aggregation, sharding, bulk indexing — mỗi bài demo THẬT trên một node Elasticsearch trong Docker, đo bằng số liệu thật.
12/12 phần đã đăng
Lập trình
1
Inverted index: vì sao Elasticsearch tìm toàn văn nhanh hơn LIKE của SQL
LIKE '%từ%' trong SQL phải quét từng dòng — chậm dần khi dữ liệu lớn. Elasticsearch lật ngược bài toán bằng inverted index: mỗi từ trỏ thẳng tới danh sách tài liệu chứa nó. Bài này đo thật trên es-lab với 100.000 tài liệu: truy vấn match dùng inverted index chạy 1 ms, còn wildcard quét từ điển term mất 8-10 ms — cùng kết quả, và khoảng cách lớn dần theo quy mô.
22/09/2026
· 7 phút đọc
2
Analyzer trong Elasticsearch: vì sao tìm 'fox jump' lại khớp 'The foxes are jumping'
Inverted index tra theo từ, nhưng 'từ' là gì do analyzer quyết định — và nó quyết luôn truy vấn của bạn khớp hay trượt. Bài này đo thật trên es-lab: standard analyzer tách và hạ chữ thường, english analyzer còn stemming (foxes thành fox), keyword giữ nguyên cả chuỗi. Xem token thật sinh ra, vì sao Email khớp email, và cách edge_ngram tạo autocomplete.
22/09/2026
· 7 phút đọc
3
match, term hay match_phrase: vì sao term 'Quick' trả về 0 kết quả dù dữ liệu có
Ba loại truy vấn hay nhầm nhất trong Elasticsearch, và một cạm bẫy kinh điển: term tìm 'Quick' trên trường text trả về 0 kết quả dù tài liệu rõ ràng chứa chữ đó. Bài này đo thật trên es-lab: match phân tích query (quick HOẶC brown), match_phrase đòi đúng thứ tự, còn term khớp token y nguyên không qua analyzer — nên hợp cho keyword, sai cho text.
22/09/2026
· 6 phút đọc
4
Relevance và BM25: đọc explain API để hiểu vì sao Elasticsearch xếp kết quả thế này
Elasticsearch không chỉ trả về tài liệu khớp — nó chấm điểm và xếp hạng bằng thuật toán BM25. Bài này đo thật trên es-lab bằng explain API: cùng tìm một từ, tài liệu chứa nó 3 lần được 0,645 điểm, tài liệu câu ngắn chứa 1 lần được 0,554, còn tài liệu câu dài 16 từ chỉ 0,248. Mổ xẻ từng thành phần TF, IDF, field length để biết vì sao.
22/09/2026
· 7 phút đọc
5
Bool query: must, should, filter, must_not — và vì sao filter cho _score bằng 0
Truy vấn thật hiếm khi chỉ một điều kiện: tìm 'wireless' NHƯNG chỉ hãng logi, còn hàng, giá dưới 50. Bool query ghép chúng lại. Bài này đo thật trên es-lab bốn mệnh đề must/should/filter/must_not: filter cho _score=0 (không tính điểm, được cache), must/should cộng điểm BM25, và khớp nhiều should thì điểm càng cao. Chọn đúng mệnh đề quyết định cả thứ tự lẫn hiệu năng.
22/09/2026
· 6 phút đọc
6
Aggregation trong Elasticsearch: gom nhóm và thống kê 1 triệu bản ghi trong 50 mili giây
Elasticsearch không chỉ tìm kiếm — nó là một cỗ máy phân tích. Bài này đo thật trên es-lab với 1 triệu bản ghi: terms gom nhóm theo danh mục trong 28ms, stats tính min/max/avg/sum trong 40ms, histogram phân bố trong 51ms. Và một cạm bẫy quan trọng: cardinality đếm khách duy nhất trả về 99.776 trong khi thực tế là 100.000 — vì nó là ước lượng, không chính xác.
22/09/2026
· 7 phút đọc
7
Mapping Elasticsearch: text hay keyword, và vì sao sort trên trường text lại báo lỗi
Mapping là schema của index Elasticsearch — và chọn sai kiểu làm hỏng truy vấn mà không báo lỗi lúc index. Bài này đo thật trên es-lab: sort trên trường text báo lỗi Fielddata is disabled, số gửi dạng chuỗi bị ES đoán thành text (mất phép toán số học), và đổi kiểu một field đã có là bất khả thi — phải reindex. Hiểu text vs keyword và mapping động vs tường minh.
22/09/2026
· 6 phút đọc
8
Bulk indexing: vì sao nạp 2000 tài liệu bằng _bulk nhanh hơn 303 lần nạp từng cái
Nạp dữ liệu vào Elasticsearch từng document một là cái bẫy hiệu năng lớn nhất khi khởi tạo index. Bài này đo thật trên es-lab: nạp 2000 tài liệu từng cái mất 8,2 giây (244 docs/giây), còn _bulk một request chỉ 27ms (74.074 docs/giây) — nhanh hơn 303 lần. Và đo luôn tác động của kích thước lô: lớn hơn thì nhanh hơn nhưng giảm dần.
22/09/2026
· 6 phút đọc
9
Deep paging trong Elasticsearch: vì sao from=10000 báo lỗi, và search_after cứu bạn
Phân trang kiểu from/size càng lật sâu càng đắt, và Elasticsearch chặn cứng ở from=10000 với một lỗi. Bài này đo thật trên es-lab với 500.000 bản ghi: from/size tăng từ 12ms lên 30ms khi lật sâu rồi báo lỗi ở 10.000, còn search_after nhảy tới bất kỳ vị trí nào (kể cả gần cuối) chỉ 2-14ms và không giới hạn. Khi nào dùng từng cái.
22/09/2026
· 6 phút đọc
10
Shard và replica Elasticsearch: nhiều shard nạp nhanh gấp đôi, nhưng số shard là bất biến
Số shard là quyết định kiến trúc quan trọng nhất của một index Elasticsearch — và khó sửa nhất. Bài này đo thật trên es-lab: nạp 200.000 tài liệu với 1 shard mất 1.310ms, với 3 shard chỉ 674ms (ghi song song). Document được băm rải đều ~66k mỗi shard. Và trung thực về replica: trên single-node nó UNASSIGNED, cluster yellow — vì sao cần nhiều node.
22/09/2026
· 6 phút đọc
11
Fuzzy và autocomplete trong Elasticsearch: gõ 'elasticsrch' vẫn ra 'elasticsearch'
Người dùng gõ sai chính tả và gõ dở chừng — hai bài toán tìm gần đúng, hai giải pháp. Bài này đo thật trên es-lab: fuzzy query với Levenshtein distance cho 'elasticsrch' (thiếu chữ) vẫn ra 'elasticsearch', và edge_ngram cho autocomplete gõ 'ela' ra gợi ý ngay trong 0ms. Kèm đánh đổi: edge_ngram index lớn hơn 5 lần nhưng tìm cực nhanh.
22/09/2026
· 6 phút đọc
12
Tổng kết Elasticsearch: khi nào nên dùng, khi nào SQL là đủ — checklist cho backend
Mười một bài, mười một phép đo thật trong Docker. Bài tổng kết này nối tất cả thành một bảng số liệu và một checklist thực chiến: Elasticsearch giỏi gì (tìm toàn văn nhanh hơn LIKE, aggregation 1 triệu bản ghi trong 28ms, bulk 74k doc/giây), không giỏi gì (transaction, JOIN, đếm chính xác), và những cạm bẫy đo được cần tránh.
22/09/2026
· 6 phút đọc