Home > Blog > tech

Elasticsearch คืออะไร? สอน Elasticsearch ตั้งแต่เริ่มต้น สำหรับ Full-Text Search และ Log Analysis 2026

elasticsearch search guide
Elasticsearch Search Guide 2026
2026-04-08 | tech | 3500 words

ในยุคที่ข้อมูลมีปริมาณมหาศาล การค้นหาข้อมูลอย่างรวดเร็วและแม่นยำเป็นสิ่งจำเป็นอย่างยิ่ง ไม่ว่าจะเป็นการค้นหาสินค้าในเว็บ 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 ที่ทำให้โดดเด่นเหนือระบบอื่นได้แก่:

ELK Stack คืออะไร?

ELK Stack (หรือ Elastic Stack) คือชุดเครื่องมือที่ทำงานร่วมกันสำหรับ Log Management และ Data Analytics ประกอบด้วย:

Componentหน้าที่รายละเอียด
ElasticsearchSearch & Storageจัดเก็บและค้นหาข้อมูล เป็นหัวใจหลักของระบบ
LogstashData Processingรับข้อมูลจาก Source ต่างๆ แปลง Filter และส่งไป Elasticsearch
KibanaVisualizationสร้าง Dashboard, Chart, Graph สำหรับแสดงผลข้อมูล
BeatsData 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คำอธิบาย
IndexDatabaseที่เก็บข้อมูลที่เกี่ยวข้องกัน เช่น products, logs, users
DocumentRowหน่วยข้อมูลหนึ่งรายการ เก็บในรูปแบบ JSON
FieldColumnส่วนประกอบของ Document เช่น name, price, description
MappingSchemaโครงสร้างของ Document กำหนด Data Type ของแต่ละ Field
ShardPartitionส่วนย่อยของ Index ที่กระจายข้ามหลาย Node
ReplicaReplicaสำเนาของ Shard เพื่อ High Availability และเพิ่มความเร็วในการอ่าน
ClusterClusterกลุ่มของ Node ที่ทำงานร่วมกัน
NodeServerเครื่อง Server แต่ละเครื่องที่เป็นส่วนหนึ่งของ Cluster
เข้าใจ Shard: เมื่อสร้าง Index ข้อมูลจะถูกแบ่งเป็น Shard หลายชิ้น (Default 1 primary shard) แต่ละ Shard เป็น Lucene Instance ที่ทำงานอิสระ ทำให้สามารถ Query แบบ Parallel ได้ ยิ่งมีหลาย Shard ยิ่ง Query เร็ว แต่ก็ใช้ Resource มากขึ้นด้วย

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 ส่วนหลักที่ทำงานต่อเนื่องกัน:

  1. Character Filters — แปลงอักขระก่อนตัด เช่น ลบ HTML tags, แปลง & เป็น and
  2. Tokenizer — ตัดข้อความเป็นคำ (Token) เช่น Standard, Whitespace, Keyword
  3. 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 vs Text: ใช้ 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 มากมาย มีฟีเจอร์หลักดังนี้:

# 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 ทางเลือกอื่น

FeatureElasticsearchApache SolrMeilisearchTypesense
ภาษาJavaJavaRustC++
Full-Text Searchดีมากดีมากดีดี
Scalabilityดีเยี่ยมดีจำกัดปานกลาง
Analyticsดีมาก (Aggregations)ดีไม่มีพื้นฐาน
ความง่ายในการใช้ปานกลางยากง่ายมากง่าย
Resource Usageสูงสูงต่ำต่ำ
Ecosystemใหญ่มาก (ELK)ใหญ่เล็กเล็ก
Typo Toleranceดีดีดีเยี่ยมดีเยี่ยม
เหมาะกับEnterprise, LogEnterpriseProduct SearchProduct Search
เลือกอะไรดี? ถ้าต้องการ Full-Text Search + Log Analytics + Scale ใหญ่ เลือก Elasticsearch ถ้าต้องการ Search สำหรับ E-commerce ง่ายๆ ลองดู Meilisearch หรือ Typesense ที่ตั้งค่าง่ายกว่ามาก

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

คำสั่งที่ใช้บ่อย (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 /_reindexCopy ข้อมูลข้าม 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 ได้เร็วที่สุด


Back to Blog | iCafe Forex | SiamLanCard | Siam2R