สรุปย่อ (TL;DR)
API ของ Elasticsearch ขับเคลื่อนการค้นหาและการวิเคราะห์ในขนาดใหญ่ คุณสามารถจัดทำเอกสารเป็น JSON, ค้นหาด้วย DSL ที่ทรงพลัง และรวบรวมผลลัพธ์เพื่อการวิเคราะห์ การยืนยันตัวตนใช้ API keys หรือ basic auth สำหรับการทดสอบ ให้ใช้ Apidog เพื่อตรวจสอบการแมปดัชนี ทดสอบการค้นหา และแก้ไขข้อผิดพลาดของการรวบรวมข้อมูลก่อนที่จะปรับใช้กับคลัสเตอร์การผลิต
บทนำ
Elasticsearch เป็นเอ็นจิ้นการค้นหาและการวิเคราะห์แบบกระจาย มันจัดการข้อความที่มีโครงสร้าง, บันทึก (logs), เมตริก (metrics) และอื่นๆ บริษัทต่างๆ ใช้สำหรับการค้นหาแบบเต็มข้อความในแอป, การวิเคราะห์บันทึกเพื่อการดีบัก และแดชบอร์ดการวิเคราะห์แบบเรียลไทม์
Elasticsearch เป็นหัวใจสำคัญของสแต็ก ELK (Elasticsearch, Logstash, Kibana) แต่คุณสามารถใช้งานได้โดยตรงผ่าน API โดยไม่ต้องใช้ Logstash
ทดสอบ Elasticsearch API ด้วย Apidog - ฟรี
เมื่อจบบทความนี้ คุณจะสามารถ:
- จัดทำและจัดการเอกสาร
- เขียนคำค้นหาด้วย Elasticsearch DSL
- ใช้การรวบรวมข้อมูลเพื่อการวิเคราะห์
- กำหนดค่าการแมปและตัววิเคราะห์
- ตรวจสอบสุขภาพของคลัสเตอร์
เริ่มต้นใช้งาน
เรียกใช้ Elasticsearch บนเครื่องของคุณ
# Docker
docker run -p 9200:9200 \
-e "discovery.type=single-node" \
elasticsearch:8.11.0
# หรือดาวน์โหลดจาก elastic.co
ตรวจสอบการติดตั้ง
curl -X GET "http://localhost:9200"
การตอบกลับ:
{
"name": "elasticsearch-1",
"cluster_name": "elasticsearch",
"cluster_uuid": "abc123",
"version": {
"number": "8.11.0",
"build_flavor": "default"
},
"tagline": "You know, for search"
}
การยืนยันตัวตน
Elasticsearch 8.x ต้องการการยืนยันตัวตนโดยค่าเริ่มต้น:
curl -X GET "http://localhost:9200/_cluster/health" \
-u elastic:your_password
หรือใช้ API keys (สร้างใน Kibana หรือผ่าน API)
ดัชนีและเอกสาร
สร้างดัชนี
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" }
}
}
}'
จัดทำเอกสาร
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"
}'
การตอบกลับ:
{
"_index": "products",
"_id": "abc123",
"_version": 1,
"result": "created",
"_seq_no": 0,
"_primary_term": 1
}
ดึงข้อมูลเอกสาร
curl -X GET "http://localhost:9200/products/_doc/abc123" \
-u elastic:your_password
อัปเดตเอกสาร
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"
}'
ลบเอกสาร
curl -X DELETE "http://localhost:9200/products/_doc/abc123" \
-u elastic:your_password
การดำเนินการแบบกลุ่ม
จัดทำเอกสารหลายฉบับอย่างมีประสิทธิภาพ:
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}
'
การค้นหา
การค้นหาพื้นฐาน
curl -X GET "http://localhost:9200/products/_search" \
-u elastic:your_password \
-H "Content-Type: application/json" \
-d '{
"query": {
"match": {
"name": "headphones"
}
}
}'
การค้นหาแบบ Bool
รวมเงื่อนไขหลายข้อ:
{
"query": {
"bool": {
"must": [
{ "match": { "name": "headphones" } }
],
"filter": [
{ "term": { "category": "electronics" } },
{ "range": { "price": { "lte": 100 } } },
{ "term": { "in_stock": true } }
]
}
}
}
การค้นหาแบบเต็มข้อความพร้อมการให้คะแนน
{
"query": {
"multi_match": {
"query": "wireless audio headphones",
"fields": ["name^2", "description"],
"type": "best_fields",
"fuzziness": "AUTO"
}
}
}
ชื่อฟิลด์ที่มี ^2 จะได้รับน้ำหนักเพิ่มขึ้นเป็นสองเท่าในการให้คะแนน
การค้นหาวลี
ค้นหาวลีที่ตรงกันเป๊ะ:
{
"query": {
"match_phrase": {
"description": "noise canceling"
}
}
}
ไวลด์การ์ดและ Regex
{
"query": {
"wildcard": {
"name": "*headphone*"
}
}
}
การเรียงลำดับ
{
"query": { "match_all": {} },
"sort": [
{ "price": "asc" },
{ "_score": "desc" }
]
}
การแบ่งหน้า
{
"from": 20,
"size": 10,
"query": { "match_all": {} }
}
การรวบรวมข้อมูล
การรวบรวมข้อมูลจะคำนวณสถิติสรุปจากข้อมูลของคุณ
ราคาเฉลี่ยตามหมวดหมู่
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" } }
}
}
}
}'
ฮิสโตแกรมของราคา
{
"size": 0,
"aggs": {
"price_histogram": {
"histogram": {
"field": "price",
"interval": 25
}
}
}
}
ฮิสโตแกรมวันที่
{
"size": 0,
"aggs": {
"sales_over_time": {
"date_histogram": {
"field": "created_at",
"calendar_interval": "month"
}
}
}
}
คาร์ดินาลิตี้ (จำนวนที่ไม่ซ้ำกัน)
{
"size": 0,
"aggs": {
"unique_categories": {
"cardinality": { "field": "category" }
}
}
}
การแมปและตัววิเคราะห์
ประเภทฟิลด์
| ประเภท | ใช้สำหรับ |
|---|---|
text |
ค้นหาข้อความเต็ม, วิเคราะห์แล้ว |
keyword |
ค่าที่แน่นอน, การกรอง, การเรียงลำดับ |
integer, float |
ตัวเลข |
boolean |
จริง/เท็จ |
date |
วันที่และเวลา |
object |
ออบเจกต์ JSON ที่ซ้อนกัน |
nested |
อาร์เรย์ของออบเจกต์ (รักษาความสัมพันธ์) |
geo_point |
พิกัดละติจูด/ลองจิจูด |
ตัววิเคราะห์แบบกำหนดเอง
สำหรับการประมวลผลข้อความเฉพาะทาง:
{
"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"
}
}
}
}
การจัดการคลัสเตอร์
สุขภาพของคลัสเตอร์
curl -X GET "http://localhost:9200/_cluster/health"
การตอบกลับ:
{
"cluster_name": "elasticsearch",
"status": "green",
"number_of_nodes": 3,
"active_primary_shards": 25
}
สถานะ:
- green: ชาร์ดทั้งหมดได้รับการจัดสรรแล้ว
- yellow: สำเนา (Replicas) ไม่ได้รับการจัดสรร (โหนดเดียว)
- red: ชาร์ดหลักหายไป
สถิติดัชนี
curl -X GET "http://localhost:9200/_cat/indices?v"
สถิติโหนด
curl -X GET "http://localhost:9200/_nodes/stats"
ล้างแคช
curl -X POST "http://localhost:9200/_cache/clear"
การทดสอบด้วย Apidog
การค้นหาใน Elasticsearch อาจซับซ้อน ควรทดสอบอย่างละเอียด

1. บันทึกการค้นหาที่ใช้บ่อย
จัดเก็บเทมเพลตการค้นหาใน Apidog:
{
"query": {
"bool": {
"must": [
{ "match": { "{{search_field}}": "{{search_term}}" } }
],
"filter": [
{ "range": { "{{price_field}}": { "lte": "{{max_price}}" } } }
]
}
}
}
2. ตรวจสอบการตอบกลับ
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. การแยกสภาพแวดล้อม
# โลคัล
ES_HOST: http://localhost:9200
ES_USER: elastic
ES_PASSWORD: your_password
# การผลิต
ES_HOST: https://search.yourcompany.com
ES_API_KEY: prod_api_key
ทดสอบ Elasticsearch API ด้วย Apidog - ฟรี
ข้อผิดพลาดทั่วไปและการแก้ไข
403 Forbidden
สาเหตุ: การยืนยันตัวตนล้มเหลวหรือไม่มีสิทธิ์เพียงพอ
วิธีแก้ไข: ตรวจสอบข้อมูลรับรอง ตรวจสอบว่า API key มีสิทธิ์ดัชนีที่ถูกต้อง
404 index_not_found_exception
สาเหตุ: ดัชนีไม่มีอยู่
วิธีแก้ไข: สร้างดัชนีก่อน หรือใช้การสร้างอัตโนมัติ (เปิดใช้งานโดยค่าเริ่มต้น แต่ไม่แนะนำสำหรับการผลิต)
circuit_breaking_exception
สาเหตุ: การค้นหาใช้หน่วยความจำมากเกินไป
วิธีแก้ไข: ลดพารามิเตอร์ size, ทำให้การค้นหาง่ายขึ้น, เพิ่มตัวกรองเพื่อลดชุดผลลัพธ์
search_phase_execution_exception
สาเหตุ: ข้อผิดพลาดทางไวยากรณ์ในการค้นหา
วิธีแก้ไข: ตรวจสอบ JSON ของคุณ ปัญหาทั่วไป: เครื่องหมายคำพูดขาดหาย, เส้นทางฟิลด์ไม่ถูกต้อง
ทางเลือกและการเปรียบเทียบ
| คุณสมบัติ | Elasticsearch | OpenSearch | Meilisearch | Typesense |
|---|---|---|---|---|
| การติดตั้ง | โฮสต์เอง | โฮสต์เอง | ไบนารีเดียว | ไบนารีเดียว |
| คุณภาพการค้นหา | ยอดเยี่ยม | ดี | ยอดเยี่ยม | ดี |
| ความยากในการเรียนรู้ | สูงชัน | สูงชัน | ง่าย | ง่าย |
| ความสามารถในการปรับขนาด | ยอดเยี่ยม | ยอดเยี่ยม | ดี | ดี |
| บริการคลาวด์ | Elastic Cloud | OpenSearch Serverless | Meilisearch Cloud | Typesense Cloud |
Elasticsearch มีคุณสมบัติและชุมชนที่ใหญ่ที่สุด Meilisearch และ Typesense นั้นง่ายกว่าสำหรับการค้นหาพื้นฐาน
กรณีการใช้งานจริง
การค้นหาสำหรับอีคอมเมิร์ซ เว็บไซต์ค้าปลีกจัดทำดัชนีสินค้า 100,000 รายการ ผู้ใช้ค้นหาตามชื่อ คำอธิบาย หมวดหมู่ และช่วงราคา ระบบเติมข้อความอัตโนมัติจะแนะนำสินค้าขณะที่พิมพ์ ตัวกรองจะจำกัดผลลัพธ์ตามหมวดหมู่และความพร้อมใช้งาน
บันทึกแอปพลิเคชัน ทีม DevOps ส่งบันทึกไปยัง Elasticsearch ผ่าน Filebeat วิศวกรค้นหาบันทึกตามบริการ ระดับความรุนแรง และช่วงเวลา แดชบอร์ดแสดงอัตราข้อผิดพลาดและเวลาตอบสนอง
การวิเคราะห์ความปลอดภัย ทีมความปลอดภัยจัดทำดัชนีบันทึกเครือข่าย พวกเขาค้นหาที่อยู่ IP ที่น่าสงสัย แสดงภาพรูปแบบการรับส่งข้อมูล และแจ้งเตือนเมื่อตรวจพบความผิดปกติผ่านการรวบรวมข้อมูล
สรุป
นี่คือสิ่งที่คุณได้เรียนรู้:
- จัดทำเอกสารเป็น JSON
- ค้นหาด้วย Elasticsearch DSL
- ใช้การรวบรวมข้อมูลเพื่อการวิเคราะห์
- กำหนดค่าการแมปสำหรับการค้นหาที่ดีที่สุด
- ตรวจสอบสุขภาพของคลัสเตอร์
ขั้นตอนต่อไปของคุณ:
- เรียกใช้ Elasticsearch บนเครื่องของคุณ
- สร้างดัชนีพร้อมการแมป
- จัดทำเอกสารทดสอบบางส่วน
- เขียนคำค้นหา
- ลองใช้การรวบรวมข้อมูล
ทดสอบ Elasticsearch API ด้วย Apidog - ฟรี
คำถามที่พบบ่อย
ความแตกต่างระหว่าง Elasticsearch และ Solr คืออะไร? ทั้งคู่เป็นเอ็นจิ้นการค้นหาที่ใช้ Lucene Elasticsearch มีการออกแบบแบบกระจายและ API ที่ดีกว่า Solr มีคุณสมบัติระดับองค์กรมากกว่า โครงการใหม่ส่วนใหญ่เลือกใช้ Elasticsearch
ฉันจะจัดการอักขระพิเศษในการค้นหาได้อย่างไร? Escape อักขระพิเศษ: ()[]{}:^\"\\+-!~*?| ด้วยเครื่องหมายแบ็กสแลช หรือใช้ simple_query_string ซึ่งจะผ่อนปรนมากกว่า
ชาร์ดคืออะไร? ชาร์ดคือส่วนต่างๆ ของดัชนี ชาร์ดแต่ละอันคือดัชนี Lucene ชาร์ดหลักใช้สำหรับการเขียน และชาร์ดสำเนา (replica shards) เป็นสำเนาสำหรับการปรับขนาดการอ่านและความทนทานต่อความผิดพลาด
ฉันควรสร้างชาร์ดกี่ชาร์ด? กฎง่ายๆ คือ: 20-50GB ต่อชาร์ด เริ่มต้นด้วย 1 ชาร์ดหลัก แล้วเพิ่มชาร์ดสำเนา เพิ่มชาร์ดหลักเมื่อจำเป็นเท่านั้น (ไม่สามารถลดจำนวนลงได้)
ฉันสามารถเปลี่ยนการแมปหลังจากจัดทำดัชนีได้หรือไม่? ได้บางส่วน สามารถเพิ่มฟิลด์ใหม่ได้ตามต้องการ หากต้องการเปลี่ยนประเภทฟิลด์ที่มีอยู่ ต้องจัดทำดัชนีข้อมูลใหม่ ใช้เทมเพลตดัชนีเพื่อจัดการการแมปอย่างสอดคล้องกัน
พารามิเตอร์ _routing คืออะไร? กำหนดเส้นทางเอกสารไปยังชาร์ดเฉพาะโดยอิงจากค่าฟิลด์ ค่าเริ่มต้นคือ _id ใช้ routing เมื่อการค้นหาจะกรองตามฟิลด์เฉพาะเสมอ (เช่น user_id) เพื่อประสิทธิภาพที่ดีขึ้น
ฉันจะจัดการข้อมูลตามเวลาได้อย่างไร? ใช้ดัชนีตามวันที่: logs-2026.03.24 วิธีนี้ช่วยให้คุณสามารถลบข้อมูลเก่าโดยการลบดัชนี และปรับปรุงประสิทธิภาพการค้นหาโดยการค้นหาในดัชนีที่น้อยลง
