Tóm tắt
API của Elasticsearch cung cấp khả năng tìm kiếm và phân tích dữ liệu quy mô lớn. Bạn sẽ lập chỉ mục tài liệu dưới dạng JSON, truy vấn bằng DSL mạnh mẽ và tổng hợp kết quả để phân tích. Xác thực sử dụng khóa API hoặc xác thực cơ bản. Để kiểm thử, hãy sử dụng Apidog để xác thực ánh xạ chỉ mục, kiểm thử các truy vấn tìm kiếm và gỡ lỗi tổng hợp trước khi triển khai lên các cụm sản xuất.
Giới thiệu
Elasticsearch là công cụ tìm kiếm và phân tích phân tán, xử lý văn bản có cấu trúc, nhật ký, số liệu,... Thường dùng cho tìm kiếm toàn văn trong ứng dụng, phân tích nhật ký và bảng điều khiển thời gian thực.
Elasticsearch là thành phần trung tâm của bộ ELK (Elasticsearch, Logstash, Kibana) nhưng có thể sử dụng API trực tiếp mà không cần Logstash.
💡 Nếu bạn xây dựng các tính năng tìm kiếm hoặc phân tích nhật ký, Apidog giúp kiểm thử truy vấn, xác thực ánh xạ và gỡ lỗi tổng hợp. Bạn cũng có thể lưu mẫu tìm kiếm và chia sẻ với nhóm.
Kiểm thử API Elasticsearch với Apidog - miễn phí
Sau hướng dẫn này, bạn sẽ biết cách:
- Lập chỉ mục và quản lý tài liệu
- Viết truy vấn tìm kiếm bằng DSL của Elasticsearch
- Sử dụng tổng hợp để phân tích
- Cấu hình ánh xạ và bộ phân tích
- Giám sát tình trạng cụm
Bắt đầu
Chạy Elasticsearch cục bộ
# Docker
docker run -p 9200:9200 \
-e "discovery.type=single-node" \
elasticsearch:8.11.0
# Hoặc tải về từ elastic.co
Xác minh cài đặt
curl -X GET "http://localhost:9200"
Phản hồi mẫu:
{
"name": "elasticsearch-1",
"cluster_name": "elasticsearch",
"cluster_uuid": "abc123",
"version": {
"number": "8.11.0",
"build_flavor": "default"
},
"tagline": "You know, for search"
}
Xác thực
Elasticsearch 8.x yêu cầu xác thực mặc định:
curl -X GET "http://localhost:9200/_cluster/health" \
-u elastic:your_password
Bạn cũng có thể dùng khóa API (tạo trong Kibana hoặc qua API).
Chỉ mục và tài liệu
Tạo một chỉ mục
curl -X PUT "http://localhost:9200/products" \
-u elastic:your_password \
-H "Content-Type: application/json" \
-d '{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
},
"mappings": {
"properties": {
"name": { "type": "text" },
"price": { "type": "float" },
"category": { "type": "keyword" },
"in_stock": { "type": "boolean" },
"created_at": { "type": "date" }
}
}
}'
Lập chỉ mục một tài liệu
curl -X POST "http://localhost:9200/products/_doc" \
-u elastic:your_password \
-H "Content-Type: application/json" \
-d '{
"name": "Wireless Headphones",
"price": 79.99,
"category": "electronics",
"in_stock": true,
"created_at": "2026-03-24T10:00:00Z"
}'
Phản hồi mẫu:
{
"_index": "products",
"_id": "abc123",
"_version": 1,
"result": "created",
"_seq_no": 0,
"_primary_term": 1
}
Lấy một tài liệu
curl -X GET "http://localhost:9200/products/_doc/abc123" \
-u elastic:your_password
Cập nhật một tài liệu
curl -X PUT "http://localhost:9200/products/_doc/abc123" \
-u elastic:your_password \
-H "Content-Type: application/json" \
-d '{
"name": "Wireless Headphones Pro",
"price": 99.99,
"category": "electronics",
"in_stock": true,
"created_at": "2026-03-24T10:00:00Z"
}'
Xóa một tài liệu
curl -X DELETE "http://localhost:9200/products/_doc/abc123" \
-u elastic:your_password
Các thao tác hàng loạt
Lập chỉ mục nhiều tài liệu hiệu quả bằng bulk API:
curl -X POST "http://localhost:9200/products/_bulk" \
-u elastic:your_password \
-H "Content-Type: application/x-ndjson" \
-d '{"index":{"_id":"1"}}
{"name":"Product A","price":10.99,"category":"books","in_stock":true}
{"index":{"_id":"2"}}
{"name":"Product B","price":20.99,"category":"electronics","in_stock":false}
'
Truy vấn tìm kiếm
Tìm kiếm cơ bản
curl -X GET "http://localhost:9200/products/_search" \
-u elastic:your_password \
-H "Content-Type: application/json" \
-d '{
"query": {
"match": {
"name": "headphones"
}
}
}'
Truy vấn Bool
Kết hợp nhiều điều kiện với bool query:
{
"query": {
"bool": {
"must": [
{ "match": { "name": "headphones" } }
],
"filter": [
{ "term": { "category": "electronics" } },
{ "range": { "price": { "lte": 100 } } },
{ "term": { "in_stock": true } }
]
}
}
}
Tìm kiếm toàn văn với tính điểm
{
"query": {
"multi_match": {
"query": "wireless audio headphones",
"fields": ["name^2", "description"],
"type": "best_fields",
"fuzziness": "AUTO"
}
}
}
Trường name^2 có trọng số gấp đôi khi tính điểm.
Tìm kiếm cụm từ chính xác
{
"query": {
"match_phrase": {
"description": "noise canceling"
}
}
}
Ký tự đại diện và biểu thức chính quy
{
"query": {
"wildcard": {
"name": "*headphone*"
}
}
}
Sắp xếp
{
"query": { "match_all": {} },
"sort": [
{ "price": "asc" },
{ "_score": "desc" }
]
}
Phân trang
{
"from": 20,
"size": 10,
"query": { "match_all": {} }
}
Tổng hợp
Tính toán thống kê tóm tắt trên dữ liệu.
Giá trung bình theo danh mục
curl -X GET "http://localhost:9200/products/_search" \
-u elastic:your_password \
-H "Content-Type: application/json" \
-d '{
"size": 0,
"aggs": {
"by_category": {
"terms": { "field": "category" },
"aggs": {
"avg_price": { "avg": { "field": "price" } },
"min_price": { "min": { "field": "price" } },
"max_price": { "max": { "field": "price" } }
}
}
}
}'
Biểu đồ tần suất giá
{
"size": 0,
"aggs": {
"price_histogram": {
"histogram": {
"field": "price",
"interval": 25
}
}
}
}
Biểu đồ tần suất ngày
{
"size": 0,
"aggs": {
"sales_over_time": {
"date_histogram": {
"field": "created_at",
"calendar_interval": "month"
}
}
}
}
Đếm số lượng duy nhất (Cardinality)
{
"size": 0,
"aggs": {
"unique_categories": {
"cardinality": { "field": "category" }
}
}
}
Ánh xạ và bộ phân tích
Loại trường
| Loại | Dùng cho |
|---|---|
text |
Tìm kiếm toàn văn, được phân tích |
keyword |
Giá trị chính xác, lọc, sắp xếp |
integer, float
|
Số |
boolean |
Đúng/sai |
date |
Ngày và giờ |
object |
Đối tượng JSON lồng nhau |
nested |
Mảng các đối tượng (giữ mối quan hệ) |
geo_point |
Tọa độ vĩ độ/kinh độ |
Bộ phân tích tùy chỉnh
Tùy chỉnh xử lý văn bản nâng cao:
{
"settings": {
"analysis": {
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "autocomplete_filter"]
}
},
"filter": {
"autocomplete_filter": {
"type": "edge_ngram",
"min_gram": 2,
"max_gram": 20
}
}
}
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "standard"
}
}
}
}
Quản lý cụm
Tình trạng cụm
curl -X GET "http://localhost:9200/_cluster/health"
Phản hồi:
{
"cluster_name": "elasticsearch",
"status": "green",
"number_of_nodes": 3,
"active_primary_shards": 25
}
- green: Tất cả các shard đã phân bổ
- yellow: Một số bản sao chưa phân bổ (1 node)
- red: Thiếu shard chính
Thống kê chỉ mục
curl -X GET "http://localhost:9200/_cat/indices?v"
Thống kê node
curl -X GET "http://localhost:9200/_nodes/stats"
Xóa bộ nhớ đệm
curl -X POST "http://localhost:9200/_cache/clear"
Kiểm thử với Apidog
Các truy vấn Elasticsearch thường phức tạp – hãy kiểm thử kỹ.
1. Lưu các truy vấn phổ biến
Lưu các mẫu tìm kiếm với biến động trong Apidog:
{
"query": {
"bool": {
"must": [
{ "match": { "{{search_field}}": "{{search_term}}" } }
],
"filter": [
{ "range": { "{{price_field}}": { "lte": "{{max_price}}" } } }
]
}
}
}
2. Xác thực phản hồi
pm.test('Search returns results', () => {
const response = pm.response.json()
pm.expect(response.hits.total.value).to.be.above(0)
})
pm.test('Aggregations present', () => {
const response = pm.response.json()
pm.expect(response.aggregations).to.exist
})
3. Phân tách môi trường
# Local
ES_HOST: http://localhost:9200
ES_USER: elastic
ES_PASSWORD: your_password
# Production
ES_HOST: https://search.yourcompany.com
ES_API_KEY: prod_api_key
Kiểm thử API Elasticsearch với Apidog - miễn phí
Các lỗi và cách khắc phục phổ biến
403 Bị cấm
- Nguyên nhân: Xác thực thất bại hoặc quyền không đủ.
- Khắc phục: Kiểm tra thông tin đăng nhập. Đảm bảo khóa API có quyền truy cập đúng chỉ mục.
404 index_not_found_exception
- Nguyên nhân: Chỉ mục chưa tồn tại.
- Khắc phục: Tạo chỉ mục trước khi lập chỉ mục tài liệu, không nên dùng tự động tạo trong production.
circuit_breaking_exception
- Nguyên nhân: Truy vấn dùng quá nhiều bộ nhớ.
-
Khắc phục: Giảm tham số
size, đơn giản hóa truy vấn, thêm bộ lọc để giảm kết quả.
search_phase_execution_exception
- Nguyên nhân: Lỗi cú pháp truy vấn.
- Khắc phục: Kiểm tra JSON, chú ý dấu ngoặc kép và đường dẫn trường.
Các lựa chọn thay thế và so sánh
| Tính năng | Elasticsearch | OpenSearch | Meilisearch | Typesense |
|---|---|---|---|---|
| Cài đặt | Tự lưu trữ | Tự lưu trữ | Tệp nhị phân duy nhất | Tệp nhị phân duy nhất |
| Chất lượng tìm kiếm | Xuất sắc | Tốt | Xuất sắc | Tốt |
| Đường cong học tập | Dốc | Dốc | Dễ dàng | Dễ dàng |
| Khả năng mở rộng | Xuất sắc | Xuất sắc | Tốt | Tốt |
| Dịch vụ đám mây | Elastic Cloud | OpenSearch Serverless | Meilisearch Cloud | Typesense Cloud |
Elasticsearch đầy đủ tính năng và cộng đồng lớn nhất. Meilisearch và Typesense phù hợp cho tìm kiếm cơ bản, triển khai nhanh.
Các trường hợp sử dụng thực tế
Tìm kiếm thương mại điện tử:
Lập chỉ mục 100.000 sản phẩm. Người dùng tìm kiếm theo tên, mô tả, danh mục, giá. Tự động gợi ý khi nhập. Bộ lọc giúp thu hẹp kết quả.
Nhật ký ứng dụng:
Nhật ký gửi vào Elasticsearch qua Filebeat. Kỹ sư DevOps tìm kiếm theo dịch vụ, mức độ, thời gian. Dashboard hiển thị tỷ lệ lỗi và thời gian phản hồi.
Phân tích bảo mật:
Lập chỉ mục nhật ký mạng, tìm kiếm IP đáng ngờ, trực quan hóa mẫu lưu lượng, cảnh báo bất thường qua tổng hợp.
Tóm tắt lại
Bạn đã học được:
- Lập chỉ mục tài liệu JSON
- Truy vấn bằng DSL của Elasticsearch
- Sử dụng tổng hợp để phân tích
- Cấu hình ánh xạ tối ưu tìm kiếm
- Giám sát tình trạng cụm
Các bước tiếp theo:
- Chạy Elasticsearch cục bộ
- Tạo chỉ mục với ánh xạ
- Lập chỉ mục tài liệu kiểm thử
- Viết truy vấn tìm kiếm
- Thử tổng hợp
Kiểm thử API Elasticsearch với Apidog - miễn phí
Câu hỏi thường gặp
Khác biệt giữa Elasticsearch và Solr là gì?
Cả hai đều dựa trên Lucene. Elasticsearch thiết kế phân tán, API tốt hơn. Solr nhiều tính năng doanh nghiệp hơn. Đa số dự án mới chọn Elasticsearch.
Xử lý ký tự đặc biệt trong tìm kiếm ra sao?
Thoát các ký tự đặc biệt: ()[]{}:^\"\\+-!~*?| bằng dấu gạch chéo ngược. Hoặc dùng simple_query_string.
Shard là gì?
Shard là phần của chỉ mục. Mỗi shard là một chỉ mục Lucene. Shard chính để ghi, shard bản sao để mở rộng đọc và chịu lỗi.
Nên tạo bao nhiêu shard?
20–50GB mỗi shard. Bắt đầu với 1 shard chính, thêm bản sao khi cần. Chỉ tăng shard chính khi thực sự cần (không thể giảm).
Có thể thay đổi ánh xạ sau khi lập chỉ mục không?
Chỉ thêm trường mới. Đổi loại trường phải lập chỉ mục lại. Dùng index template để quản lý ánh xạ nhất quán.
Tham số _routing để làm gì?
Định tuyến tài liệu đến shard cụ thể dựa trên giá trị trường (mặc định _id). Có thể tối ưu hiệu suất nếu truy vấn luôn lọc theo trường nhất định (ví dụ user_id).
Xử lý dữ liệu dựa trên thời gian như thế nào?
Dùng chỉ mục theo ngày: logs-2026.03.24. Xóa dữ liệu cũ bằng cách drop index. Tối ưu truy vấn bằng cách tìm kiếm ít chỉ mục hơn.

Top comments (0)