ในยุคที่ข้อมูลมีปริมาณมหาศาล การค้นหาข้อมูลอย่างรวดเร็วและแม่นยำเป็นสิ่งจำเป็นอย่างยิ่ง ไม่ว่าจะเป็นการค้นหาสินค้าในเว็บ E-commerce การวิเคราะห์ Log ของเซิร์ฟเวอร์ หรือการทำ Analytics แบบ Real-time ทั้งหมดนี้ต้องอาศัยเทคโนโลยีที่ทรงพลัง นั่นคือ Elasticsearch ซึ่งเป็น Search Engine ที่ได้รับความนิยมสูงสุดในโลก ใช้โดยบริษัทระดับโลกอย่าง Netflix, Uber, GitHub และ Wikipedia
บทความนี้จะสอน Elasticsearch อย่างครบถ้วน ตั้งแต่แนวคิดพื้นฐาน การติดตั้ง การทำ Full-Text Search การใช้ Aggregations ไปจนถึง ELK Stack ทั้งระบบ พร้อมตัวอย่าง Query จริงที่สามารถนำไปประยุกต์ใช้ได้ทันที
Elasticsearch คืออะไร?
Elasticsearch คือ Distributed Search and Analytics Engine แบบ Open Source ที่สร้างบน Apache Lucene ออกแบบมาเพื่อจัดเก็บ ค้นหา และวิเคราะห์ข้อมูลปริมาณมากแบบ Near Real-Time สามารถค้นหาข้อมูลหลายล้าน Record ได้ภายในมิลลิวินาที
คุณสมบัติหลักของ Elasticsearch ที่ทำให้โดดเด่นเหนือระบบอื่นได้แก่:
- Full-Text Search — ค้นหาข้อความแบบเต็มรูปแบบ รองรับ Fuzzy Search, Synonym, Multi-language
- Distributed Architecture — กระจายข้อมูลออกเป็น Shard ข้ามหลาย Node ทำให้ Scale ได้ง่าย
- Near Real-Time — ข้อมูลที่ถูก Index จะค้นหาได้ภายใน 1 วินาที
- RESTful API — ทุก Operation ทำผ่าน HTTP REST API ง่ายต่อการ Integrate
- Schema-Free (Dynamic Mapping) — ไม่ต้องกำหนด Schema ล่วงหน้า Elasticsearch จะตรวจจับ Data Type อัตโนมัติ
- Aggregations — วิเคราะห์ข้อมูลเชิงสถิติได้โดยไม่ต้องใช้เครื่องมือแยก
ELK Stack คืออะไร?
ELK Stack (หรือ Elastic Stack) คือชุดเครื่องมือที่ทำงานร่วมกันสำหรับ Log Management และ Data Analytics ประกอบด้วย:
| Component | หน้าที่ | รายละเอียด |
|---|---|---|
| Elasticsearch | Search & Storage | จัดเก็บและค้นหาข้อมูล เป็นหัวใจหลักของระบบ |
| Logstash | Data Processing | รับข้อมูลจาก Source ต่างๆ แปลง Filter และส่งไป Elasticsearch |
| Kibana | Visualization | สร้าง Dashboard, Chart, Graph สำหรับแสดงผลข้อมูล |
| Beats | Data Shipper | ตัวส่งข้อมูลน้ำหนักเบา เช่น Filebeat, Metricbeat, Packetbeat |
Flow การทำงานของ ELK Stack คือ: Beats หรือ Application ส่ง Log ไปที่ Logstash ซึ่งจะ Parse และ Filter ข้อมูล จากนั้นส่งไปเก็บใน Elasticsearch และสุดท้ายใช้ Kibana เพื่อ Visualize ข้อมูลเป็น Dashboard ที่สวยงามและใช้งานง่าย
ติดตั้ง Elasticsearch
ติดตั้งด้วย Docker (แนะนำ)
# สร้าง Network สำหรับ ELK
docker network create elastic
# รัน Elasticsearch
docker run -d --name elasticsearch \
--net elastic \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e "xpack.security.enabled=false" \
-e "ES_JAVA_OPTS=-Xms1g -Xmx1g" \
docker.elastic.co/elasticsearch/elasticsearch:8.15.0
# รัน Kibana
docker run -d --name kibana \
--net elastic \
-p 5601:5601 \
-e "ELASTICSEARCH_HOSTS=http://elasticsearch:9200" \
docker.elastic.co/kibana/kibana:8.15.0
# ตรวจสอบว่าทำงาน
curl http://localhost:9200
curl http://localhost:5601/api/status
ติดตั้งด้วย Docker Compose
# docker-compose.yml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- ES_JAVA_OPTS=-Xms2g -Xmx2g
ports:
- "9200:9200"
volumes:
- esdata:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana:8.15.0
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
- elasticsearch
logstash:
image: docker.elastic.co/logstash/logstash:8.15.0
ports:
- "5044:5044"
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline
depends_on:
- elasticsearch
volumes:
esdata:
driver: local
ติดตั้งบน Ubuntu/Debian (Bare Metal)
# เพิ่ม Elasticsearch GPG key
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | \
sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
# เพิ่ม Repository
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] \
https://artifacts.elastic.co/packages/8.x/apt stable main" | \
sudo tee /etc/apt/sources.list.d/elastic-8.x.list
# ติดตั้ง
sudo apt update && sudo apt install elasticsearch
# เริ่ม Service
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
# ตรวจสอบ
curl -X GET "localhost:9200"
แนวคิดพื้นฐาน (Core Concepts)
ก่อนจะเริ่มใช้งาน Elasticsearch คุณต้องเข้าใจแนวคิดพื้นฐานเหล่านี้ ซึ่งจะช่วยให้เข้าใจวิธีการทำงานของระบบอย่างลึกซึ้งและสามารถออกแบบระบบได้อย่างมีประสิทธิภาพ:
| แนวคิด | เทียบกับ RDBMS | คำอธิบาย |
|---|---|---|
| Index | Database | ที่เก็บข้อมูลที่เกี่ยวข้องกัน เช่น products, logs, users |
| Document | Row | หน่วยข้อมูลหนึ่งรายการ เก็บในรูปแบบ JSON |
| Field | Column | ส่วนประกอบของ Document เช่น name, price, description |
| Mapping | Schema | โครงสร้างของ Document กำหนด Data Type ของแต่ละ Field |
| Shard | Partition | ส่วนย่อยของ Index ที่กระจายข้ามหลาย Node |
| Replica | Replica | สำเนาของ Shard เพื่อ High Availability และเพิ่มความเร็วในการอ่าน |
| Cluster | Cluster | กลุ่มของ Node ที่ทำงานร่วมกัน |
| Node | Server | เครื่อง Server แต่ละเครื่องที่เป็นส่วนหนึ่งของ Cluster |
CRUD Operations พื้นฐาน
สร้าง Index
# สร้าง Index ใหม่
PUT /products
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"name": { "type": "text", "analyzer": "standard" },
"description": { "type": "text" },
"price": { "type": "float" },
"category": { "type": "keyword" },
"in_stock": { "type": "boolean" },
"created_at": { "type": "date" },
"tags": { "type": "keyword" }
}
}
}
Create — เพิ่ม Document
# เพิ่ม Document (กำหนด ID)
PUT /products/_doc/1
{
"name": "iPhone 16 Pro Max",
"description": "สมาร์ทโฟนรุ่นใหม่ล่าสุดจาก Apple",
"price": 52900,
"category": "smartphones",
"in_stock": true,
"created_at": "2026-04-08",
"tags": ["apple", "iphone", "premium"]
}
# เพิ่ม Document (Auto-generate ID)
POST /products/_doc
{
"name": "Samsung Galaxy S26 Ultra",
"description": "สมาร์ทโฟน Android ระดับ Flagship",
"price": 47900,
"category": "smartphones",
"in_stock": true,
"created_at": "2026-04-08",
"tags": ["samsung", "android", "flagship"]
}
# Bulk Insert หลาย Document พร้อมกัน
POST /_bulk
{ "index": { "_index": "products", "_id": "3" } }
{ "name": "MacBook Pro M4", "price": 79900, "category": "laptops" }
{ "index": { "_index": "products", "_id": "4" } }
{ "name": "iPad Air M3", "price": 24900, "category": "tablets" }
Read — ค้นหา Document
# ดึง Document ด้วย ID
GET /products/_doc/1
# ค้นหาทั้งหมด
GET /products/_search
{
"query": { "match_all": {} }
}
# นับจำนวน Document
GET /products/_count
Update — อัปเดต Document
# อัปเดตบาง Field
POST /products/_update/1
{
"doc": {
"price": 49900,
"in_stock": false
}
}
# อัปเดตด้วย Script
POST /products/_update/1
{
"script": {
"source": "ctx._source.price -= params.discount",
"params": { "discount": 3000 }
}
}
Delete — ลบ Document
# ลบ Document
DELETE /products/_doc/1
# ลบตาม Query (ระวัง!)
POST /products/_delete_by_query
{
"query": {
"term": { "category": "outdated" }
}
}
# ลบ Index ทั้งหมด (อันตราย!)
DELETE /products
Full-Text Search อย่างละเอียด
จุดแข็งที่สำคัญที่สุดของ Elasticsearch คือ Full-Text Search ซึ่งไม่ใช่แค่การค้นหาข้อความที่ตรงกันเป๊ะ (Exact Match) แต่เป็นการค้นหาที่เข้าใจภาษามนุษย์ สามารถค้นหาคำที่ใกล้เคียง จัดลำดับความเกี่ยวข้อง และรองรับหลายภาษา
Match Query — ค้นหาพื้นฐาน
# ค้นหาจาก Field เดียว
GET /products/_search
{
"query": {
"match": {
"name": "iPhone Pro"
}
}
}
# กำหนดว่าต้อง Match ทุกคำ (AND)
GET /products/_search
{
"query": {
"match": {
"name": {
"query": "iPhone Pro",
"operator": "and"
}
}
}
}
# กำหนด Minimum ที่ต้อง Match
GET /products/_search
{
"query": {
"match": {
"description": {
"query": "สมาร์ทโฟน รุ่นใหม่ Apple",
"minimum_should_match": "75%"
}
}
}
}
Multi-Match Query — ค้นหาหลาย Field
# ค้นหาจากหลาย Field พร้อมกัน
GET /products/_search
{
"query": {
"multi_match": {
"query": "สมาร์ทโฟน premium",
"fields": ["name^3", "description", "tags^2"],
"type": "best_fields"
}
}
}
# name^3 หมายถึง Field name มีน้ำหนัก 3 เท่า
# type: best_fields, most_fields, cross_fields, phrase
Bool Query — ค้นหาแบบซับซ้อน
# รวมหลาย Condition
GET /products/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "สมาร์ทโฟน" } }
],
"filter": [
{ "range": { "price": { "gte": 20000, "lte": 50000 } } },
{ "term": { "in_stock": true } }
],
"should": [
{ "match": { "tags": "premium" } },
{ "match": { "description": "ใหม่ล่าสุด" } }
],
"must_not": [
{ "term": { "category": "accessories" } }
]
}
}
}
# must: ต้องตรง (มีผลต่อ Score)
# filter: ต้องตรง (ไม่มีผลต่อ Score, เร็วกว่า, Cache ได้)
# should: ควรตรง (เพิ่ม Score ถ้าตรง)
# must_not: ต้องไม่ตรง (ไม่มีผลต่อ Score)
Phrase Query — ค้นหาวลี
# ค้นหาวลีที่ต้องติดกัน
GET /products/_search
{
"query": {
"match_phrase": {
"description": "สมาร์ทโฟน รุ่นใหม่"
}
}
}
# อนุญาตให้มีคำคั่นระหว่างกลาง
GET /products/_search
{
"query": {
"match_phrase": {
"description": {
"query": "สมาร์ทโฟน Apple",
"slop": 2
}
}
}
}
Fuzzy Search — ค้นหาคำที่สะกดผิด
# ค้นหาคำที่สะกดใกล้เคียง
GET /products/_search
{
"query": {
"fuzzy": {
"name": {
"value": "iphne",
"fuzziness": "AUTO"
}
}
}
}
# Wildcard Search
GET /products/_search
{
"query": {
"wildcard": {
"name": {
"value": "iph*"
}
}
}
}
Analyzers และ Tokenizers
Analyzer เป็นกลไกสำคัญที่อยู่เบื้องหลังการทำ Full-Text Search ทำหน้าที่แปลงข้อความดิบเป็น Token ที่ใช้สร้าง Inverted Index ประกอบด้วย 3 ส่วนหลักที่ทำงานต่อเนื่องกัน:
- Character Filters — แปลงอักขระก่อนตัด เช่น ลบ HTML tags, แปลง & เป็น and
- Tokenizer — ตัดข้อความเป็นคำ (Token) เช่น Standard, Whitespace, Keyword
- Token Filters — แปลง Token เช่น Lowercase, Stemming, Stop Words, Synonym
# ทดสอบ Analyzer
POST /_analyze
{
"analyzer": "standard",
"text": "The Quick Brown Fox Jumped!"
}
# ผลลัพธ์: ["the", "quick", "brown", "fox", "jumped"]
# สร้าง Custom Analyzer
PUT /my_index
{
"settings": {
"analysis": {
"analyzer": {
"my_custom_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "stop", "snowball"],
"char_filter": ["html_strip"]
}
},
"filter": {
"my_synonym": {
"type": "synonym",
"synonyms": [
"โทรศัพท์, มือถือ, สมาร์ทโฟน",
"คอมพิวเตอร์, คอม, PC"
]
}
}
}
},
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "my_custom_analyzer"
}
}
}
}
keyword สำหรับ Field ที่ต้องการ Exact Match เช่น category, status, email ใช้ text สำหรับ Field ที่ต้องการ Full-Text Search เช่น name, description, content ถ้าต้องการทั้งสองแบบ ใช้ Multi-field Mapping
Aggregations — วิเคราะห์ข้อมูล
Aggregations ช่วยให้คุณวิเคราะห์ข้อมูลเชิงสถิติได้ เหมือน GROUP BY ใน SQL แต่ทรงพลังกว่ามาก สามารถ Nest หลายระดับและรวมกับ Search ได้ในคำสั่งเดียว
Metric Aggregations
# ค่าเฉลี่ย, สูงสุด, ต่ำสุด
GET /products/_search
{
"size": 0,
"aggs": {
"avg_price": { "avg": { "field": "price" } },
"max_price": { "max": { "field": "price" } },
"min_price": { "min": { "field": "price" } },
"total_value": { "sum": { "field": "price" } },
"price_stats": { "stats": { "field": "price" } }
}
}
Bucket Aggregations
# จัดกลุ่มตาม Category
GET /products/_search
{
"size": 0,
"aggs": {
"by_category": {
"terms": {
"field": "category",
"size": 10
},
"aggs": {
"avg_price": { "avg": { "field": "price" } }
}
}
}
}
# จัดกลุ่มตามช่วงราคา
GET /products/_search
{
"size": 0,
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 10000, "key": "budget" },
{ "from": 10000, "to": 30000, "key": "mid-range" },
{ "from": 30000, "to": 60000, "key": "premium" },
{ "from": 60000, "key": "ultra-premium" }
]
}
}
}
}
# Date Histogram (รายวัน, รายเดือน)
GET /logs/_search
{
"size": 0,
"aggs": {
"logs_per_day": {
"date_histogram": {
"field": "timestamp",
"calendar_interval": "day"
},
"aggs": {
"error_count": {
"filter": { "term": { "level": "error" } }
}
}
}
}
}
Kibana Dashboards
Kibana เป็นเครื่องมือ Visualization ที่ทำงานคู่กับ Elasticsearch ช่วยให้คุณสร้าง Dashboard ที่สวยงามโดยไม่ต้องเขียน Code มากมาย มีฟีเจอร์หลักดังนี้:
- Discover — สำรวจข้อมูลดิบ ค้นหาด้วย KQL (Kibana Query Language)
- Visualize — สร้างกราฟ Chart ต่างๆ เช่น Bar, Pie, Line, Area, Map, Gauge
- Dashboard — รวม Visualization หลายชิ้นเข้าด้วยกัน ดูได้ในหน้าเดียว
- Lens — สร้าง Visualization ง่ายๆ แบบ Drag-and-Drop ไม่ต้องตั้งค่าอะไรมาก
- Canvas — สร้าง Infographic แบบกำหนดเองได้อย่างอิสระ
- Maps — แสดงข้อมูลบนแผนที่ (Geo Data)
# KQL ตัวอย่าง (ใช้ใน Kibana Discover)
# ค้นหา Log ที่เป็น Error
level: "error"
# ค้นหา Log จาก Service เฉพาะ
service.name: "api-gateway" and level: "error"
# ค้นหาช่วงเวลา
@timestamp >= "2026-04-01" and @timestamp < "2026-04-09"
# ค้นหาข้อความ
message: "connection refused" or message: "timeout"
Logstash Pipelines
Logstash เป็น Data Processing Pipeline ที่ทำหน้าที่รับข้อมูลจาก Source ต่างๆ (Input) แปลงข้อมูล (Filter) และส่งไปปลายทาง (Output) โครงสร้างของ Logstash Pipeline มี 3 ส่วน:
# /etc/logstash/conf.d/main.conf
input {
# รับ Log จาก Filebeat
beats {
port => 5044
}
# รับจาก TCP
tcp {
port => 5000
codec => json_lines
}
# อ่านจากไฟล์
file {
path => "/var/log/nginx/access.log"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
# Parse Nginx Access Log
grok {
match => {
"message" => '%{IPORHOST:client_ip} - %{DATA:user} \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:http_version}" %{NUMBER:status} %{NUMBER:bytes}'
}
}
# แปลง timestamp
date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
target => "@timestamp"
}
# เพิ่ม GeoIP
geoip {
source => "client_ip"
}
# แปลง Type
mutate {
convert => {
"status" => "integer"
"bytes" => "integer"
}
remove_field => ["message", "host"]
}
# เพิ่ม Field ตามเงื่อนไข
if [status] >= 400 {
mutate { add_tag => ["error"] }
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "nginx-logs-%{+YYYY.MM.dd}"
}
# Debug: แสดงใน Console
stdout {
codec => rubydebug
}
}
Filebeat สำหรับ Log Collection
Filebeat เป็น Lightweight Log Shipper ที่ทำหน้าที่ส่ง Log ไปยัง Logstash หรือ Elasticsearch โดยตรง ใช้ Resource น้อยกว่า Logstash มาก เหมาะกับการติดตั้งบนทุกเครื่อง Server
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
fields:
service: nginx
multiline:
pattern: '^\['
negate: true
match: after
- type: log
enabled: true
paths:
- /var/log/app/*.log
fields:
service: myapp
json.keys_under_root: true
json.add_error_key: true
# ส่งไปที่ Logstash
output.logstash:
hosts: ["logstash:5044"]
# หรือส่งไปที่ Elasticsearch โดยตรง
# output.elasticsearch:
# hosts: ["elasticsearch:9200"]
# index: "filebeat-%{+yyyy.MM.dd}"
# Processors
processors:
- add_host_metadata: ~
- add_cloud_metadata: ~
- drop_fields:
fields: ["agent.ephemeral_id", "agent.hostname"]
Index Lifecycle Management (ILM)
ILM ช่วยจัดการ Index อัตโนมัติตาม Lifecycle ที่กำหนด ตั้งแต่สร้าง Index ใหม่ จนถึงลบ Index เก่า เหมาะอย่างยิ่งสำหรับ Log Data ที่มีปริมาณเพิ่มขึ้นทุกวัน ช่วยควบคุม Storage ไม่ให้เต็ม
# สร้าง ILM Policy
PUT /_ilm/policy/logs_policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_primary_shard_size": "50GB",
"max_age": "1d"
},
"set_priority": { "priority": 100 }
}
},
"warm": {
"min_age": "7d",
"actions": {
"shrink": { "number_of_shards": 1 },
"forcemerge": { "max_num_segments": 1 },
"set_priority": { "priority": 50 }
}
},
"cold": {
"min_age": "30d",
"actions": {
"freeze": {},
"set_priority": { "priority": 0 }
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}
# ผูก Policy กับ Index Template
PUT /_index_template/logs_template
{
"index_patterns": ["logs-*"],
"template": {
"settings": {
"index.lifecycle.name": "logs_policy",
"index.lifecycle.rollover_alias": "logs",
"number_of_shards": 3,
"number_of_replicas": 1
}
}
}
Performance Tuning
การ Tune Performance ของ Elasticsearch เป็นทักษะสำคัญที่ช่วยให้ระบบทำงานได้เร็วและเสถียร โดยเฉพาะเมื่อมีข้อมูลปริมาณมาก ต่อไปนี้คือเทคนิคสำคัญที่ควรรู้:
JVM Heap Size
# ตั้ง Heap Size ไม่เกินครึ่งของ RAM ทั้งหมด
# และไม่เกิน 32GB (Compressed OOPs limit)
# jvm.options
-Xms16g
-Xmx16g
# หรือผ่าน Environment Variable
ES_JAVA_OPTS="-Xms16g -Xmx16g"
Indexing Performance
# เพิ่ม Refresh Interval (Default 1s)
PUT /my_index/_settings
{
"index.refresh_interval": "30s"
}
# ปิด Refresh ระหว่าง Bulk Index
PUT /my_index/_settings
{
"index.refresh_interval": "-1"
}
# Bulk Size ที่เหมาะสม: 5-15 MB ต่อ Bulk Request
# ใช้ Bulk API แทน Single Document API เสมอ
# ลด Replica ระหว่าง Initial Load
PUT /my_index/_settings
{
"number_of_replicas": 0
}
# เสร็จแล้วค่อยเพิ่มกลับ
PUT /my_index/_settings
{
"number_of_replicas": 1
}
Search Performance
# ใช้ Filter แทน Query เมื่อไม่ต้องการ Scoring
# Filter จะถูก Cache ทำให้เร็วขึ้นมาก
# ใช้ Source Filtering — ดึงเฉพาะ Field ที่ต้องการ
GET /products/_search
{
"_source": ["name", "price"],
"query": { "match_all": {} }
}
# ใช้ Preference เพื่อใช้ Shard Cache
GET /products/_search?preference=_local
{
"query": { "match": { "name": "iPhone" } }
}
# Profile Query เพื่อหา Bottleneck
GET /products/_search
{
"profile": true,
"query": { "match": { "name": "iPhone" } }
}
Security — X-Pack Security
ใน Production ต้องเปิด Security เสมอ Elasticsearch 8.x มี Security เปิดโดย Default สิ่งที่ต้องตั้งค่าได้แก่:
# elasticsearch.yml
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
# TLS สำหรับ HTTP
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
# TLS สำหรับ Transport (ระหว่าง Node)
xpack.security.transport.ssl:
enabled: true
keystore.path: certs/transport.p12
verification_mode: certificate
# สร้าง Password สำหรับ Built-in Users
bin/elasticsearch-setup-passwords auto
# สร้าง User ใหม่
POST /_security/user/app_user
{
"password": "strong_password_here",
"roles": ["app_reader"],
"full_name": "Application User"
}
# สร้าง Role
POST /_security/role/app_reader
{
"indices": [
{
"names": ["products*", "logs*"],
"privileges": ["read", "view_index_metadata"]
}
]
}
# API Key (สำหรับ Application)
POST /_security/api_key
{
"name": "my-app-key",
"role_descriptors": {
"app_role": {
"indices": [
{
"names": ["products*"],
"privileges": ["read"]
}
]
}
}
}
Elasticsearch vs ทางเลือกอื่น
| Feature | Elasticsearch | Apache Solr | Meilisearch | Typesense |
|---|---|---|---|---|
| ภาษา | Java | Java | Rust | C++ |
| Full-Text Search | ดีมาก | ดีมาก | ดี | ดี |
| Scalability | ดีเยี่ยม | ดี | จำกัด | ปานกลาง |
| Analytics | ดีมาก (Aggregations) | ดี | ไม่มี | พื้นฐาน |
| ความง่ายในการใช้ | ปานกลาง | ยาก | ง่ายมาก | ง่าย |
| Resource Usage | สูง | สูง | ต่ำ | ต่ำ |
| Ecosystem | ใหญ่มาก (ELK) | ใหญ่ | เล็ก | เล็ก |
| Typo Tolerance | ดี | ดี | ดีเยี่ยม | ดีเยี่ยม |
| เหมาะกับ | Enterprise, Log | Enterprise | Product Search | Product Search |
Use Cases ที่ใช้จริง
1. Log Analysis (ELK Stack)
เก็บ Log จากทุก Server, Application, Container รวมไว้ที่เดียว ค้นหาและวิเคราะห์ปัญหาได้อย่างรวดเร็ว เป็น Use Case ที่นิยมที่สุดของ Elasticsearch เพราะสามารถจัดการ Log หลายล้าน Event ต่อวินาทีได้
2. Product Search (E-commerce)
สร้างระบบค้นหาสินค้าที่ฉลาด เข้าใจคำค้นหาที่สะกดผิด มี Auto-complete, Suggestion, Filter ตาม Category ช่วงราคา และ Faceted Search ที่แสดงจำนวนสินค้าในแต่ละหมวดหมู่
3. Application Performance Monitoring (APM)
Elastic APM ช่วย Monitor Performance ของ Application ดู Trace ของ Request, ตรวจจับ Slow Query, วิเคราะห์ Error Rate ระบุปัญหาก่อนที่ผู้ใช้จะรู้สึก
4. Security Analytics (SIEM)
Elastic Security ใช้ Elasticsearch เป็น Backend สำหรับ Security Information and Event Management (SIEM) วิเคราะห์ Log ด้านความปลอดภัย ตรวจจับ Threat, Anomaly และทำ Incident Response
5. Business Analytics
วิเคราะห์ข้อมูลธุรกิจแบบ Real-time เช่น จำนวน Order ต่อชั่วโมง Revenue per Region, User Behavior Analysis ด้วย Aggregation ที่ทรงพลัง สร้าง Dashboard ที่อัปเดตอัตโนมัติ
ตัวอย่างการใช้งานจริง — E-commerce Search
# สร้าง Index สำหรับสินค้า พร้อม Custom Analyzer
PUT /shop_products
{
"settings": {
"analysis": {
"analyzer": {
"thai_analyzer": {
"type": "custom",
"tokenizer": "icu_tokenizer",
"filter": ["lowercase", "icu_folding"]
},
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "edge_ngram_filter"]
}
},
"filter": {
"edge_ngram_filter": {
"type": "edge_ngram",
"min_gram": 2,
"max_gram": 15
}
}
}
},
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "thai_analyzer",
"fields": {
"autocomplete": {
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "standard"
},
"keyword": {
"type": "keyword"
}
}
},
"description": { "type": "text", "analyzer": "thai_analyzer" },
"category": { "type": "keyword" },
"brand": { "type": "keyword" },
"price": { "type": "float" },
"rating": { "type": "float" },
"sold_count": { "type": "integer" },
"created_at": { "type": "date" }
}
}
}
# Autocomplete Query
GET /shop_products/_search
{
"query": {
"match": {
"name.autocomplete": {
"query": "iph"
}
}
},
"highlight": {
"fields": {
"name": {}
}
}
}
# E-commerce Search พร้อม Faceted Search
GET /shop_products/_search
{
"query": {
"bool": {
"must": [
{ "multi_match": {
"query": "โทรศัพท์มือถือ",
"fields": ["name^3", "description"]
} }
],
"filter": [
{ "range": { "price": { "gte": 5000, "lte": 30000 } } }
]
}
},
"aggs": {
"categories": {
"terms": { "field": "category", "size": 20 }
},
"brands": {
"terms": { "field": "brand", "size": 20 }
},
"price_ranges": {
"histogram": { "field": "price", "interval": 5000 }
},
"avg_rating": {
"avg": { "field": "rating" }
}
},
"sort": [
{ "_score": "desc" },
{ "sold_count": "desc" }
],
"size": 20
}
Best Practices
- Mapping: กำหนด Mapping เองเสมอ ไม่ควรพึ่ง Dynamic Mapping ใน Production เพราะอาจได้ Type ที่ไม่ต้องการ
- Shard Sizing: Shard ควรมีขนาดระหว่าง 10-50 GB สำหรับ Time-based Data ใช้ ILM เพื่อ Rollover อัตโนมัติ
- Bulk API: ใช้ Bulk API เสมอเมื่อ Index หลาย Document ขนาด Bulk ที่เหมาะสมคือ 5-15 MB ต่อ Request
- Filter vs Query: ใช้ Filter ใน bool query สำหรับเงื่อนไขที่ไม่ต้องการ Scoring จะเร็วกว่ามากเพราะ Cache ได้
- Monitoring: ใช้ Kibana Stack Monitoring หรือ _cat API เพื่อตรวจสอบสุขภาพของ Cluster เสมอ
- Backup: ใช้ Snapshot API สำหรับ Backup ข้อมูลสำคัญไปเก็บใน S3, GCS หรือ NFS
- Security: เปิด TLS + Authentication เสมอใน Production อย่าเปิด Elasticsearch ให้เข้าถึงจาก Internet โดยไม่มี Security
- Resource: Elasticsearch ต้องการ RAM มาก ควรจัดสรร JVM Heap ไม่เกินครึ่งของ RAM ที่มี และเหลือ RAM อีกครึ่งสำหรับ OS File Cache
คำสั่งที่ใช้บ่อย (Quick Reference)
| คำสั่ง | หน้าที่ |
|---|---|
GET /_cat/health?v | ดูสถานะ Cluster |
GET /_cat/nodes?v | ดู Node ทั้งหมด |
GET /_cat/indices?v | ดู Index ทั้งหมด |
GET /_cat/shards?v | ดู Shard ทั้งหมด |
GET /_cluster/health | สถานะ Cluster (JSON) |
GET /_cluster/stats | สถิติ Cluster |
PUT /index_name | สร้าง Index |
DELETE /index_name | ลบ Index |
POST /_reindex | Copy ข้อมูลข้าม Index |
POST /_forcemerge | รวม Segment |
สรุป
Elasticsearch เป็นเครื่องมือที่ทรงพลังอย่างมากสำหรับ Full-Text Search และ Data Analytics ด้วยความสามารถในการจัดการข้อมูลปริมาณมหาศาลและค้นหาได้อย่างรวดเร็ว ทำให้เป็นตัวเลือกอันดับหนึ่งสำหรับหลายกรณีใช้งาน ตั้งแต่ Log Analysis ไปจนถึง E-commerce Search
เมื่อรวมกับ ELK Stack ทั้งระบบ (Elasticsearch, Logstash, Kibana, Beats) คุณจะได้แพลตฟอร์มที่ครบครันสำหรับการจัดเก็บ ประมวลผล ค้นหา และแสดงผลข้อมูลในที่เดียว ไม่ว่าจะเป็นองค์กรเล็กหรือใหญ่ Elasticsearch สามารถ Scale ตามความต้องการได้เสมอ
สิ่งสำคัญคือการเริ่มต้นจากพื้นฐานที่แน่น เข้าใจ Mapping, Analyzer, Query DSL และ Aggregation ก่อน แล้วค่อยขยายไปใช้ ELK Stack เต็มรูปแบบ การลงมือทำจริงโดยการ Index ข้อมูลจริงและทดลอง Query ต่างๆ จะช่วยให้เข้าใจ Elasticsearch ได้เร็วที่สุด
