Doc Values trong Elasticsearch: Vì sao lại cần?
Khi làm việc với Elasticsearch, chúng ta thường nghe tới doc_values. Nhưng thực chất nó là gì, và tại sao lại quan trọng đến vậy? Bài viết này sẽ đi sâu từ cấu trúc inverted index, lý do nó mạnh cho full-text search nhưng yếu cho sort/aggregation, cho tới sự ra đời của doc_values.
Inverted Index – Linh hồn của Full-text Search
Elasticsearch (dựa trên Lucene) lưu dữ liệu bằng inverted index.
Ví dụ với 3 document:
1: { "title": "Elasticsearch is fast" }
2: { "title": "Search is powerful" }
3: { "title": "Fast search engine" }
Sau khi tokenize, inverted index cho field title sẽ là:
| Term | Doc IDs |
|---|---|
| elasticsearch | [1] |
| engine | [3] |
| fast | [1, 3] |
| is | [1, 2] |
| powerful | [2] |
| search | [2, 3] |
👉 Với query "fast search", Elasticsearch chỉ cần giao nhau [1,3] và [2,3] → kết quả là Doc 3.
Rõ ràng inverted index cực mạnh cho full-text search.
Vấn đề: Sort và Aggregation
Giả sử ta có dữ liệu:
1: { "price": 100 }
2: { "price": 300 }
3: { "price": 200 }
Inverted index cho field price:
| Term (price) | Doc IDs |
|---|---|
| 100 | [1] |
| 200 | [3] |
| 300 | [2] |
👉 Nếu query "sort by price asc":
- Elasticsearch phải duyệt toàn bộ inverted index, lôi ra
(docId, value)rồi mới sort. - Với hàng trăm triệu document, tất cả dữ liệu phải load vào RAM (fielddata cũ) → cực kỳ tốn bộ nhớ, dễ OOM.
Tương tự với aggregation (avg(price), terms, histogram…), Elasticsearch cũng phải gom hết giá trị vào bộ nhớ trước khi tính toán.
➡️ Inverted index không phù hợp cho sort/aggregation vì nó được thiết kế cho lookup term → docIds, không phải docId → value.
Doc Values – Column Store cho Sort & Aggregation
Để giải quyết vấn đề này, Elasticsearch (từ 2.0) bổ sung doc_values.
- Nếu inverted index là
term → docIds - Thì doc_values lưu ngược lại:
docId → value(column-oriented storage).
Ví dụ field price sẽ thành:
| Doc ID | Price |
|---|---|
| 1 | 100 |
| 2 | 300 |
| 3 | 200 |
Đặc điểm:
- Lưu ở disk theo dạng columnar, được mmap vào memory khi cần.
- Hỗ trợ đọc trực tiếp giá trị để sort, tính toán, script.
- Không cần giữ toàn bộ trong heap memory.
So sánh: Inverted Index vs Doc Values
| Đặc điểm | Inverted Index (term → docIds) |
Doc Values (docId → value) |
|---|---|---|
| Tối ưu cho | Full-text search | Sort, Aggregation, Scripting |
| Vị trí lưu | Disk (inverted files) | Disk (column store, mmap) |
| RAM tiêu thụ | Cao nếu sort/agg dùng fielddata | Thấp, ổn định trên dataset lớn |
| Bật mặc định | Có (cho text/keyword search) | Có (cho hầu hết numeric, keyword) |
| Nhược điểm | Không dùng tốt cho sort/agg | Tốn thêm dung lượng lưu trữ |
Best Practices: Khi nào bật hoặc tắt Doc Values?
Trong thực tế, doc_values được bật mặc định cho hầu hết các field (keyword, numeric, date, geo_point, v.v.), và bạn chỉ cần quan tâm khi tối ưu storage.
✅ Giữ doc_values (mặc định) nếu:
- Field dùng cho sort hoặc aggregation.
- Field tham gia scripting hoặc filter phức tạp.
- Dữ liệu cần báo cáo thống kê (ví dụ:
price,created_at,status).
❌ Tắt doc_values nếu:
- Field chỉ dùng để search full-text, ví dụ
textfield phân tích nội dung văn bản. - Field chỉ dùng để index & match (ví dụ: log message, description), không bao giờ cần sort/agg.
- Khi dataset quá lớn, việc bật doc_values cho mọi field gây tốn disk space không cần thiết.
👉 Bạn có thể tắt bằng mapping:
"mappings": {
"properties": {
"message": {
"type": "text",
"doc_values": false
}
}
}
🎯 Kinh nghiệm:
- Đừng vội tắt bừa: Elasticsearch cần doc_values nhiều hơn bạn nghĩ.
- Với log system lớn: giữ doc_values cho
timestamp,level,service_id; tắt chomessage. - Với e-commerce: giữ doc_values cho
price,category,created_at; tắt chodescription.
Tóm lại
- Inverted index: trái tim của Elasticsearch, cực mạnh cho full-text search.
- Nhưng nó không phù hợp cho sort/aggregation do phải đảo dữ liệu vào RAM.
- Doc Values được sinh ra để lưu giá trị dạng cột, hỗ trợ sort/agg nhanh, ổn định, ít tốn RAM hơn.
- Trong thực tế, hãy giữ mặc định, chỉ tắt
doc_valueskhi chắc chắn field đó không bao giờ dùng cho sort/aggregation để tiết kiệm dung lượng.
👉 Nắm rõ sự khác biệt này giúp bạn vừa hiểu Elasticsearch sâu hơn, vừa tối ưu storage và hiệu năng khi làm việc với dataset lớn.