ElasticSearch Full-text Search สร้างระบบค้นหาอัจฉริยะ

ในยุคที่ข้อมูลมีปริมาณมหาศาลและเพิ่มขึ้นอย่างต่อเนื่อง การค้นหาข้อมูลที่แม่นยำ รวดเร็ว และตรงใจผู้ใช้งานคือหัวใจสำคัญของการสร้างประสบการณ์ดิจิทัลที่เหนือกว่า ไม่ว่าจะเป็นเว็บไซต์ E-commerce ที่ต้องการให้ลูกค้าหาสินค้าที่ใช่ได้ในพริบตา ระบบจัดการเอกสารภายในองค์กรที่ต้องเข้าถึงข้อมูลสำคัญได้อย่างฉับไว หรือแม้แต่แพลตฟอร์มโซเชียลมีเดียที่ต้องแสดงผลเนื้อหาที่เกี่ยวข้องกับผู้ใช้ การค้นหาแบบดั้งเดิมที่พึ่งพาฐานข้อมูลเชิงสัมพันธ์เพียงอย่างเดียวอาจไม่เพียงพออีกต่อไปครับ

วันนี้ SiamLancard.com ขอพาทุกท่านดำดิ่งสู่โลกของ Elasticsearch Full-text Search สุดยอดเครื่องมือที่จะพลิกโฉมระบบค้นหาของคุณให้กลายเป็น “ระบบค้นหาอัจฉริยะ” ที่ไม่เพียงแค่หาคำที่ตรงกัน แต่ยังเข้าใจบริบท ความหมาย และความเกี่ยวข้องของข้อมูล เพื่อนำเสนอผลลัพธ์ที่ดีที่สุดแก่ผู้ใช้งานได้อย่างแท้จริงครับ บทความนี้จะเจาะลึกทุกแง่มุม ตั้งแต่พื้นฐาน สถาปัตยกรรม การใช้งานจริง ไปจนถึงเทคนิคขั้นสูงในการสร้างระบบค้นหาที่ทรงพลังและปรับขนาดได้ เรามาดูกันครับว่า Elasticsearch จะเข้ามาช่วยแก้ปัญหาและยกระดับการค้นหาของคุณได้อย่างไร

สารบัญ

1. ทำความเข้าใจ Full-text Search คืออะไร?

ก่อนที่เราจะลงลึกไปกับ Elasticsearch เรามาทำความเข้าใจพื้นฐานของ “Full-text Search” กันก่อนครับว่ามันคืออะไร และแตกต่างจากการค้นหาข้อมูลแบบดั้งเดิมอย่างไร

1.1. ข้อจำกัดของการค้นหาแบบดั้งเดิม

โดยปกติแล้ว เมื่อเราพูดถึงการค้นหาข้อมูลในฐานข้อมูลเชิงสัมพันธ์ (Relational Database) เช่น MySQL หรือ PostgreSQL เรามักจะใช้คำสั่ง SQL อย่าง LIKE '%คำค้นหา%' หรือ WHERE column = 'ค่าที่ต้องการ' ซึ่งมีข้อจำกัดหลายประการครับ

  • ความเร็ว: การใช้ LIKE '%คำค้นหา%' มักจะต้องสแกนข้อมูลทั้งตาราง ซึ่งทำให้ช้ามากหากข้อมูลมีจำนวนมาก
  • ความแม่นยำ (Exact Match): มักจะค้นหาได้เพียงคำที่ตรงกันทั้งหมดเท่านั้น หากสะกดผิดไปเล็กน้อย หรือมีคำพ้องความหมายก็จะไม่เจอ
  • ความเกี่ยวข้อง (Relevance): ไม่สามารถบอกได้ว่าผลลัพธ์ใดมีความเกี่ยวข้องกับคำค้นหามากที่สุด
  • การวิเคราะห์ข้อความ: ไม่สามารถจัดการกับภาษาธรรมชาติ การแยกคำ (tokenization) การตัดคำท้าย (stemming) หรือการจัดการคำพ้องความหมายได้
  • ความยืดหยุ่น: ยากที่จะสร้างฟังก์ชันการค้นหาขั้นสูง เช่น การค้นหาตามวลี (phrase search), การค้นหาแบบคลุมเครือ (fuzzy search) หรือการให้คะแนนความเกี่ยวข้อง

ข้อจำกัดเหล่านี้ทำให้การสร้างระบบค้นหาที่ดีขึ้นอยู่กับ SQL เพียงอย่างเดียวเป็นเรื่องที่ท้าทายและไม่ตอบโจทย์ความต้องการของผู้ใช้งานในปัจจุบันครับ

1.2. หลักการทำงานของ Full-text Search: Inverted Index

Full-text Search ได้รับการออกแบบมาเพื่อแก้ปัญหาเหล่านี้ โดยมีหัวใจหลักอยู่ที่โครงสร้างข้อมูลที่เรียกว่า “Inverted Index” (ดัชนีผกผัน) ครับ

ลองนึกภาพว่าเรามีหนังสือหลายเล่ม และต้องการหาว่าคำว่า “Elasticsearch” ปรากฏอยู่ในหนังสือเล่มไหนบ้าง หน้าไหนบ้าง หากไม่มีดัชนี เราก็ต้องเปิดอ่านทีละหน้าใช่ไหมครับ?

Inverted Index ทำงานคล้ายกับดัชนีท้ายเล่มหนังสือครับ แต่กลับด้านกัน โดยแทนที่จะระบุว่า “หนังสือเล่มนี้มีเนื้อหาอะไรบ้าง” มันจะระบุว่า “คำนี้ปรากฏอยู่ที่ไหนบ้าง”

กระบวนการทำงานเบื้องต้นของ Inverted Index มีดังนี้ครับ

  1. การวิเคราะห์ข้อความ (Text Analysis):
    • Tokenization: ข้อความดิบจะถูกแบ่งออกเป็นคำ ๆ (tokens) เช่น “Elasticsearch is powerful” จะถูกแบ่งเป็น “Elasticsearch”, “is”, “powerful”
    • Normalization: คำเหล่านี้จะถูกทำให้เป็นรูปแบบมาตรฐาน เช่น แปลงเป็นตัวพิมพ์เล็กทั้งหมด (“Elasticsearch” -> “elasticsearch”), ลบเครื่องหมายวรรคตอน
    • Stop Words Removal: ลบคำทั่วไปที่ไม่มีนัยยะสำคัญ เช่น “is”, “a”, “the” ออกไป
    • Stemming/Lemmatization: ตัดคำท้ายหรือแปลงคำให้อยู่ในรูปคำศัพท์พื้นฐาน เช่น “running”, “ran”, “runs” อาจถูกแปลงเป็น “run” เพื่อให้สามารถค้นหาคำที่มีรากเดียวกันได้
  2. การสร้าง Inverted Index: หลังจากผ่านการวิเคราะห์แล้ว คำ (terms) ที่ได้จะถูกนำมาสร้างเป็นดัชนี โดยแต่ละคำจะเชื่อมโยงกับเอกสาร (document) ที่มีคำนั้นปรากฏอยู่ พร้อมทั้งข้อมูลเสริม เช่น ตำแหน่งที่ปรากฏ, ความถี่ที่ปรากฏ

ตัวอย่าง Inverted Index แบบง่าย:

{
  "elasticsearch": [
    { "document_id": "doc1", "positions": [1, 5] },
    { "document_id": "doc2", "positions": [3] }
  ],
  "powerful": [
    { "document_id": "doc1", "positions": [2] },
    { "document_id": "doc3", "positions": [1] }
  ],
  "search": [
    { "document_id": "doc2", "positions": [4] }
  ]
}

เมื่อผู้ใช้ค้นหาคำว่า “elasticsearch” ระบบจะไปดูที่ Inverted Index ทันที และรู้ได้ทันทีว่าคำนี้อยู่ใน doc1 และ doc2 โดยไม่ต้องสแกนเนื้อหาทั้งหมด ทำให้การค้นหาเป็นไปอย่างรวดเร็วและมีประสิทธิภาพครับ

1.3. ประโยชน์ของ Full-text Search

ด้วยหลักการทำงานของ Inverted Index ทำให้ Full-text Search มีประโยชน์อย่างมหาศาลครับ

  • ความเร็วสูง: ค้นหาข้อมูลจำนวนมากได้ในเวลาอันสั้น
  • ความเกี่ยวข้อง (Relevance): สามารถให้คะแนน (score) ความเกี่ยวข้องของผลลัพธ์ได้ ทำให้แสดงผลลัพธ์ที่ดีที่สุดก่อน
  • ความยืดหยุ่นในการค้นหา: รองรับการค้นหาที่ซับซ้อน เช่น การค้นหาตามวลี, การค้นหาแบบคลุมเครือ, การค้นหาคำพ้องความหมาย
  • การจัดการภาษาธรรมชาติ: สามารถวิเคราะห์และทำความเข้าใจบริบทของภาษาได้ดีขึ้น
  • Scalability: ออกแบบมาให้รองรับข้อมูลปริมาณมหาศาลและผู้ใช้งานจำนวนมากได้

2. ทำไมต้องเป็น ElasticSearch สำหรับ Full-text Search?

ในโลกของ Full-text Search มีเครื่องมืออยู่หลายตัว แต่ Elasticsearch ได้รับความนิยมอย่างแพร่หลายและกลายเป็นมาตรฐานอุตสาหกรรมในหลาย ๆ ด้าน ด้วยความสามารถที่โดดเด่นและครบวงจรครับ

2.1. ความสามารถในการปรับขนาด (Scalability)

Elasticsearch ถูกออกแบบมาตั้งแต่แรกให้เป็นระบบแบบกระจาย (distributed system) ครับ สิ่งนี้หมายความว่าคุณสามารถเพิ่ม “โหนด” (Node) หรือเซิร์ฟเวอร์เข้าไปใน “คลัสเตอร์” (Cluster) ได้อย่างง่ายดาย เพื่อเพิ่มทั้งความสามารถในการจัดเก็บข้อมูลและประมวลผลการค้นหาได้อย่างไร้รอยต่อ

  • Horizontal Scaling: เพิ่มเครื่องเซิร์ฟเวอร์ได้เรื่อย ๆ เพื่อรองรับข้อมูลที่เติบโตขึ้น
  • Fault Tolerance: หากมีโหนดใดโหนดหนึ่งล้มเหลว ระบบยังคงทำงานได้ตามปกติ เนื่องจากข้อมูลมีการสำรองไว้ (replicas)

นี่คือจุดแข็งสำคัญที่ทำให้ Elasticsearch เหมาะสำหรับระบบที่มีข้อมูลขนาดใหญ่และมีการเติบโตสูงครับ

2.2. ความเร็วในการค้นหา (Near Real-time Search)

Elasticsearch สามารถจัดทำดัชนีข้อมูลและทำให้ข้อมูลนั้นพร้อมสำหรับการค้นหาได้เกือบจะในทันที (near real-time) ครับ หมายความว่าเมื่อคุณเพิ่ม แก้ไข หรือลบข้อมูล ข้อมูลนั้นจะพร้อมสำหรับการค้นหาภายในไม่กี่วินาที ซึ่งเป็นสิ่งสำคัญสำหรับแอปพลิเคชันที่ต้องการความสดใหม่ของข้อมูล เช่น ระบบ E-commerce ที่มีการอัปเดตสต็อกสินค้าบ่อยครั้ง หรือระบบ Log Analysis ที่ต้องการดูข้อมูลแบบเรียลไทม์ครับ

2.3. ความสามารถในการวิเคราะห์ข้อความที่เหนือกว่า (Advanced Text Analysis)

Elasticsearch มีระบบ Text Analysis ที่ซับซ้อนและปรับแต่งได้สูงครับ คุณสามารถกำหนด “Analyzer” (ตัววิเคราะห์) ของคุณเองได้ เพื่อให้เหมาะสมกับภาษาและประเภทข้อมูลที่คุณมี ไม่ว่าจะเป็นการตัดคำสำหรับภาษาไทย การจัดการคำพ้องความหมาย การลบ Stop Words ที่เฉพาะเจาะจง หรือการใช้ Stemming สำหรับภาษาอื่น ๆ สิ่งนี้ช่วยให้ผลลัพธ์การค้นหาแม่นยำและเกี่ยวข้องกับผู้ใช้มากขึ้นครับ

2.4. ภาษา Query ที่ทรงพลัง (Query DSL)

Elasticsearch มี “Query DSL” (Domain Specific Language) ที่เป็น JSON-based ซึ่งทรงพลังและยืดหยุ่นอย่างมากครับ คุณสามารถสร้าง Query ที่ซับซ้อนได้หลากหลายรูปแบบ เช่น

  • ค้นหาคำที่ตรงกัน (match query)
  • ค้นหาตามวลี (phrase query)
  • การค้นหาแบบ Boolean (AND, OR, NOT)
  • การค้นหาแบบคลุมเครือ (fuzzy query) ที่ยอมให้มีการสะกดผิดเล็กน้อย
  • การกรองข้อมูล (filtering)
  • การจัดลำดับผลลัพธ์ (sorting)
  • การทำไฮไลต์ (highlighting)
  • การรวมกลุ่มข้อมูล (aggregations) เพื่อวิเคราะห์ข้อมูลเชิงลึก

ความสามารถเหล่านี้ช่วยให้คุณสร้างประสบการณ์การค้นหาที่เหนือกว่าที่ผู้ใช้คาดหวังได้ครับ

2.5. Ecosystem ที่ครบวงจร (ELK Stack)

Elasticsearch ไม่ได้มาเดี่ยว ๆ ครับ แต่เป็นส่วนหนึ่งของ “ELK Stack” (ปัจจุบันเรียกว่า Elastic Stack) ซึ่งประกอบด้วย:

  • Elasticsearch: ตัว Search Engine หลัก
  • Logstash: เครื่องมือสำหรับรวบรวม ประมวลผล และจัดเก็บข้อมูล
  • Kibana: เครื่องมือสำหรับวิเคราะห์ แสดงผลข้อมูล (visualization) และสร้าง Dashboard ที่สวยงาม
  • Beats: ตัวรวบรวมข้อมูลขนาดเล็กที่ติดตั้งบนเซิร์ฟเวอร์เพื่อส่งข้อมูลไปยัง Logstash หรือ Elasticsearch โดยตรง

ELK Stack ทำให้การจัดการข้อมูลตั้งแต่การรวบรวม การจัดเก็บ การค้นหา ไปจนถึงการวิเคราะห์และแสดงผลเป็นไปอย่างราบรื่นและครบวงจร เหมาะสำหรับ Use Case หลากหลาย เช่น Log Analysis, Monitoring, และ Business Intelligence ครับ

3. สถาปัตยกรรมพื้นฐานของ ElasticSearch (Core Concepts)

การเข้าใจสถาปัตยกรรมและ Core Concepts ของ Elasticsearch เป็นสิ่งสำคัญในการออกแบบและจัดการระบบค้นหาที่มีประสิทธิภาพครับ

3.1. Cluster, Node, Shard, Replica

เหล่านี้คือองค์ประกอบหลักที่ทำให้ Elasticsearch มีความสามารถในการปรับขนาดและทนทานต่อความผิดพลาดครับ

  • Cluster (คลัสเตอร์):
    • คือกลุ่มของโหนด (Node) หนึ่งชุดที่ทำงานร่วมกันเพื่อจัดเก็บข้อมูลทั้งหมดของคุณ และให้ความสามารถในการจัดทำดัชนีและการค้นหาแบบกระจาย
    • คลัสเตอร์จะมีชื่อเฉพาะ (เช่น elasticsearch โดยค่าเริ่มต้น)
  • Node (โหนด):
    • คือเซิร์ฟเวอร์เดี่ยว ๆ ที่เป็นส่วนหนึ่งของคลัสเตอร์
    • แต่ละโหนดเก็บข้อมูลบางส่วนของคลัสเตอร์ และมีส่วนร่วมในการจัดทำดัชนีและการค้นหา
    • โหนดมีหน้าที่ต่างกันได้ เช่น master-eligible node (ดูแลการบริหารคลัสเตอร์), data node (เก็บข้อมูล), ingest node (สำหรับ pre-processing), coordinating node (กระจายคำขอไปยังโหนดอื่น)
  • Shard (ชาร์ด):
    • คือหน่วยย่อยของ Index ที่เล็กที่สุดครับ ข้อมูลใน Index จะถูกแบ่งออกเป็น Shard เล็ก ๆ หลาย ๆ Shard
    • แต่ละ Shard เป็นเหมือน Index อิสระขนาดเล็กที่มีความสามารถในการค้นหาและจัดทำดัชนีได้ด้วยตัวเอง
    • การแบ่งข้อมูลเป็น Shard ช่วยให้ Elasticsearch สามารถกระจายข้อมูลและการประมวลผลไปยังหลาย ๆ โหนดได้ ทำให้เกิด Scalability ครับ
    • มีสองประเภทคือ:
      • Primary Shard: เป็น Shard ต้นฉบับที่เก็บข้อมูลจริง
      • Replica Shard: เป็นสำเนาของ Primary Shard
  • Replica (เรพลิกา):
    • คือสำเนาของ Primary Shard ครับ
    • มีประโยชน์หลัก ๆ สองอย่าง:
      1. Fault Tolerance: หาก Primary Shard เกิดล้มเหลว Replica Shard สามารถเข้ามาทำหน้าที่แทนได้ทันที ทำให้ข้อมูลไม่สูญหายและระบบยังคงทำงานได้
      2. Increased Search Performance: คำขอค้นหาสามารถถูกส่งไปยัง Primary Shard หรือ Replica Shard ก็ได้ ทำให้สามารถกระจายโหลดและเพิ่มประสิทธิภาพการค้นหาได้ครับ
    • โดยทั่วไปแล้ว แต่ละ Primary Shard ควรจะมีอย่างน้อย 1 Replica Shard ครับ

ลองจินตนาการว่าคุณมี Index ขนาดใหญ่หนึ่งอัน Elasticsearch จะแบ่ง Index นั้นเป็น Primary Shard หลาย ๆ อัน (เช่น 5 อัน) และแต่ละ Primary Shard ก็จะมี Replica Shard อีกหลาย ๆ อัน (เช่น 1 อัน) รวมเป็น 5 Primary Shard + 5 Replica Shard = 10 Shard ซึ่ง Shard เหล่านี้จะกระจายไปอยู่ตาม Node ต่าง ๆ ใน Cluster ครับ

3.2. Index, Document, Type (และเหตุผลที่ถูกเลิกใช้)

เหล่านี้คือหน่วยในการจัดเก็บและจัดการข้อมูลครับ

  • Index (อินเด็กซ์):
    • เปรียบเสมือน “ฐานข้อมูล” ในโลกของฐานข้อมูลเชิงสัมพันธ์ หรือ “คอลเลกชัน” ใน NoSQL
    • เป็นที่เก็บรวบรวมของเอกสารที่มีโครงสร้างคล้ายกัน
    • แต่ละ Index มี Mapping (Schema) และ Analyzer เป็นของตัวเอง
    • คุณสามารถมีหลาย Index ใน Cluster เดียวได้ เช่น products index, users index, orders index
  • Document (เอกสาร):
    • คือหน่วยข้อมูลพื้นฐานที่สุดใน Elasticsearch ครับ เปรียบเสมือน “แถว” (Row) ในฐานข้อมูลเชิงสัมพันธ์
    • แต่ละ Document เป็นโครงสร้างข้อมูลแบบ JSON ที่สามารถจัดเก็บข้อมูลได้หลากหลายประเภท (ข้อความ, ตัวเลข, วันที่, Boolean, ออบเจกต์ซ้อนกัน)
    • แต่ละ Document ใน Index จะมี ID ที่ไม่ซ้ำกัน
  • Type (ไทป์):
    • ใน Elasticsearch เวอร์ชั่นเก่า (ก่อน 7.0) Type เปรียบเสมือน “ตาราง” (Table) ภายใน Index
    • แต่ในเวอร์ชั่นใหม่ ๆ Type ถูกเลิกใช้ไปแล้วครับ (Deprecated) และจะถูกลบออกไปทั้งหมดในอนาคต
    • เหตุผลก็คือ ในฐานข้อมูลเชิงสัมพันธ์ แต่ละตารางมี Schema ที่แตกต่างกัน แต่ใน Elasticsearch ทุก Type ภายใน Index เดียวกันจะต้องแชร์ Inverted Index เดียวกัน ทำให้เกิดปัญหาด้านประสิทธิภาพและการจัดการข้อมูลในบางสถานการณ์
    • แนวทางปฏิบัติปัจจุบัน: ควรมีเพียง 1 Type ต่อ 1 Index หรือมองว่า Index คือ Type ไปเลยครับ เช่น แทนที่จะมี Index ชื่อ blog และมี Type posts กับ comments ให้สร้างเป็น blog_posts Index และ blog_comments Index แทนครับ

3.3. Mapping และ Analyzers

สองสิ่งนี้คือหัวใจสำคัญของการกำหนดว่าข้อมูลจะถูกจัดเก็บและค้นหาได้อย่างไรครับ

  • Mapping (การแมป):
    • คือ Schema ของ Index ครับ มันจะกำหนดว่าแต่ละ Field ใน Document มีประเภทข้อมูลอะไร (เช่น text, keyword, integer, date) และควรจะถูกประมวลผลอย่างไร
    • Dynamic Mapping: Elasticsearch มีความสามารถในการเดาประเภทข้อมูลของ Field โดยอัตโนมัติเมื่อ Document ถูก Index เป็นครั้งแรก
    • Explicit Mapping: คุณสามารถกำหนด Mapping ด้วยตัวเองได้ เพื่อควบคุมการทำงานของ Full-text Search ได้อย่างละเอียด เช่น กำหนด Analyzer เฉพาะสำหรับบาง Field, กำหนดว่าจะให้ Field ใดถูกค้นหาได้บ้าง
    • Data Types ที่สำคัญ:
      • text: สำหรับข้อความที่ต้องการ Full-text Search (จะถูก Analyze)
      • keyword: สำหรับข้อความที่ต้องการค้นหาแบบตรงตัว (Exact Match) เช่น ชื่อสินค้า รหัสไปรษณีย์ (จะไม่ถูก Analyze)
      • integer, float, long, double: สำหรับตัวเลข
      • date: สำหรับวันที่และเวลา
      • boolean: สำหรับค่าจริง/เท็จ
      • object, nested: สำหรับโครงสร้างข้อมูลที่ซับซ้อนภายใน Document
  • Analyzers (ตัววิเคราะห์):
    • คือกระบวนการที่ใช้ในการแปลงข้อความดิบให้เป็น “terms” ที่จะถูกเก็บใน Inverted Index
    • ประกอบด้วย 3 ส่วนหลัก:
      1. Character Filters: ทำงานก่อน Tokenizer เพื่อทำความสะอาดข้อความ เช่น ลบแท็ก HTML, แทนที่อักขระพิเศษ
      2. Tokenizer: แบ่งข้อความเป็น “tokens” (คำ) เช่น Standard Tokenizer, Whitespace Tokenizer, Thai Tokenizer
      3. Token Filters: ประมวลผล tokens ที่ได้จาก Tokenizer อีกครั้ง เช่น lowercase filter, stop word filter, stemmer filter, synonym filter
    • การเลือกและปรับแต่ง Analyzer ที่เหมาะสมเป็นสิ่งสำคัญมากสำหรับคุณภาพของ Full-text Search โดยเฉพาะสำหรับภาษาที่มีความซับซ้อนอย่างภาษาไทยครับ

4. เริ่มต้นติดตั้งและใช้งาน ElasticSearch (เบื้องต้น)

ก่อนจะลุยกับโค้ดจริง ๆ เรามาดูวิธีการติดตั้ง Elasticsearch และ Kibana แบบคร่าว ๆ กันก่อนครับ เพื่อให้มีสภาพแวดล้อมพร้อมใช้งาน

4.1. การติดตั้งเบื้องต้น

Elasticsearch สามารถติดตั้งได้หลายวิธีครับ แต่ที่นิยมคือ:

  • Docker: เป็นวิธีที่ง่ายและรวดเร็วที่สุดสำหรับการพัฒนาและทดสอบ
  • Package Managers: สำหรับ Production มักจะใช้ผ่าน APT (Debian/Ubuntu) หรือ YUM (RHEL/CentOS)
  • Manual Download: ดาวน์โหลดไฟล์ ZIP/TAR.GZ และแตกไฟล์

ตัวอย่างการติดตั้งด้วย Docker (แนะนำสำหรับ Dev):

สร้างไฟล์ docker-compose.yml:

version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.12.2
    container_name: elasticsearch
    environment:
      - xpack.security.enabled=false
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
      - 9300:9300
    networks:
      - elastic
  kibana:
    image: docker.elastic.co/kibana/kibana:8.12.2
    container_name: kibana
    ports:
      - 5601:5601
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    networks:
      - elastic
    depends_on:
      - elasticsearch
volumes:
  esdata:
    driver: local
networks:
  elastic:
    driver: bridge

จากนั้นรันคำสั่งใน Terminal ในโฟลเดอร์ที่มีไฟล์ docker-compose.yml:

docker-compose up -d

รอสักครู่ Elasticsearch และ Kibana ก็จะพร้อมใช้งานแล้วครับ

4.2. ตรวจสอบสถานะ Cluster

เมื่อ Elasticsearch รันอยู่ คุณสามารถตรวจสอบสถานะได้โดยใช้คำสั่ง HTTP GET ไปยังพอร์ต 9200 ครับ

curl -X GET "http://localhost:9200/_cat/health?v"

ผลลัพธ์ที่คาดหวัง (ถ้าทุกอย่างถูกต้อง):

epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1707010000 00:00:00  docker-cluster green         1         1      0   0    0    0        0             0                  -                100.0%

ถ้า status เป็น green แสดงว่า Cluster ของคุณทำงานได้เป็นปกติครับ

4.3. ทำความรู้จัก Kibana

Kibana คือ UI (User Interface) สำหรับ Elasticsearch ครับ เป็นเครื่องมือที่ยอดเยี่ยมสำหรับการจัดการ ตรวจสอบ และวิเคราะห์ข้อมูลใน Elasticsearch

  • คุณสามารถเข้าถึง Kibana ได้ที่ http://localhost:5601
  • ส่วนที่คุณจะใช้บ่อยที่สุดคือ “Dev Tools” ครับ ซึ่งเป็นคอนโซลที่คุณสามารถส่งคำสั่ง REST API ไปยัง Elasticsearch ได้โดยตรง คล้ายกับ Postman หรือ cURL แต่มีข้อดีคือมี Auto-completion และแสดงผล JSON ได้สวยงาม

ในตัวอย่างโค้ดต่อไปนี้ เราจะใช้ Dev Tools ของ Kibana เป็นหลักครับ

5. การจัดเก็บข้อมูลใน ElasticSearch: Indexing (การทำดัชนี)

การจัดเก็บข้อมูลใน Elasticsearch หรือที่เรียกว่า “Indexing” คือกระบวนการนำเอกสาร JSON เข้าสู่ Index เพื่อให้พร้อมสำหรับการค้นหาและวิเคราะห์ครับ

5.1. เอกสาร (Document) และ JSON

อย่างที่กล่าวไปแล้ว เอกสารคือหน่วยข้อมูลพื้นฐานใน Elasticsearch และอยู่ในรูปแบบ JSON ครับ แต่ละ Field ใน JSON จะมีค่าเป็นของตัวเอง และ Elasticsearch จะจัดเก็บและประมวลผลตาม Mapping ที่กำหนดไว้

ตัวอย่าง Document:

{
  "title": "Elasticsearch Full-text Search",
  "content": "บทความนี้จะสอนการสร้างระบบค้นหาอัจฉริยะด้วย Elasticsearch Full-text Search",
  "author": "SiamLancard Team",
  "tags": ["elasticsearch", "full-text search", "search engine", "siamlancard"],
  "publish_date": "2023-11-01T10:00:00Z",
  "views": 1500
}

5.2. การสร้าง Index และ Mapping

การสร้าง Index สามารถทำได้โดยการส่งคำขอ HTTP PUT ไปยัง /_index_name ครับ หากคุณส่ง Document ไปยัง Index ที่ยังไม่มี Elasticsearch จะสร้าง Index พร้อม Dynamic Mapping ให้โดยอัตโนมัติ

อย่างไรก็ตาม การกำหนด Explicit Mapping เป็นสิ่งสำคัญเพื่อให้การค้นหามีประสิทธิภาพและแม่นยำยิ่งขึ้นครับ โดยเฉพาะอย่างยิ่งสำหรับ Field ที่เป็นข้อความ

ตัวอย่างการสร้าง Index พร้อม Explicit Mapping สำหรับบทความ:

PUT /articles
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 1,
      "analysis": {
        "analyzer": {
          "thai_analyzer": {
            "type": "custom",
            "tokenizer": "thai",
            "filter": ["lowercase"]
          },
          "custom_english_analyzer": {
            "type": "custom",
            "tokenizer": "standard",
            "filter": ["lowercase", "stop", "kstem"]
          }
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "thai_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "content": {
        "type": "text",
        "analyzer": "thai_analyzer"
      },
      "author": {
        "type": "keyword"
      },
      "tags": {
        "type": "keyword"
      },
      "publish_date": {
        "type": "date"
      },
      "views": {
        "type": "integer"
      }
    }
  }
}

คำอธิบาย:

  • /articles: ชื่อ Index
  • settings: กำหนดค่าสำหรับ Index เช่น จำนวน Shard และ Replica
  • analysis: ส่วนสำคัญที่เรากำหนด thai_analyzer โดยใช้ tokenizer แบบ thai (ซึ่งเป็น Plugin ที่ต้องติดตั้งเพิ่ม) และ lowercase filter
  • mappings.properties: กำหนด Schema ของแต่ละ Field
    • title และ content ใช้ thai_analyzer เพื่อให้ค้นหาภาษาไทยได้ดี และ title.keyword สำหรับการค้นหาแบบตรงตัว
    • author และ tags ใช้ keyword เพื่อการค้นหาแบบตรงตัวและ Aggregation

หมายเหตุ: สำหรับการใช้ tokenizer: "thai" คุณอาจจะต้องติดตั้ง Analysis ICU Plugin ก่อนครับ โดยทั่วไปจะติดตั้งได้ด้วยคำสั่ง bin/elasticsearch-plugin install analysis-icu บนเซิร์ฟเวอร์ Elasticsearch แล้วรีสตาร์ทครับ

5.3. Analyzers ในเชิงลึก

การเลือก Analyzer ที่เหมาะสมเป็นสิ่งสำคัญมากสำหรับคุณภาพการค้นหาครับ โดยเฉพาะสำหรับภาษาไทยที่ไม่มีการเว้นวรรคระหว่างคำอย่างชัดเจน

  • Character Filters: ประมวลผลก่อน Tokenizer
    • html_strip: ลบแท็ก HTML
    • mapping: แทนที่อักขระบางตัวด้วยตัวอื่น เช่น & เป็น and
  • Tokenizers: แบ่งข้อความเป็น Token
    • standard: Tokenizer ทั่วไปสำหรับภาษาตะวันตก
    • whitespace: แบ่งตามช่องว่าง
    • thai: Tokenizer สำหรับภาษาไทย (ต้องติดตั้ง ICU Analysis Plugin)
  • Token Filters: ประมวลผล Token ที่ได้
    • lowercase: แปลงเป็นตัวพิมพ์เล็ก
    • stop: ลบ Stop Words (เช่น “และ”, “แต่”, “ว่า” ในภาษาไทย หรือ “the”, “is”, “a” ในภาษาอังกฤษ)
    • kstem (สำหรับอังกฤษ): ทำ Stemming (ลดรูปคำ)
    • synonym: แทนที่คำด้วยคำพ้องความหมาย

คุณสามารถทดสอบ Analyzer ได้ใน Kibana Dev Tools ครับ:

POST /_analyze
{
  "analyzer": "thai_analyzer",
  "text": "Elasticsearch สร้างระบบค้นหาอัจฉริยะ"
}

ผลลัพธ์ที่ได้จะแสดง Tokens ที่ถูกสร้างขึ้นครับ

5.4. ตัวอย่างการ Index ข้อมูล

เมื่อเราสร้าง Index พร้อม Mapping แล้ว ก็ถึงเวลาเพิ่มข้อมูลครับ

POST /articles/_doc/1
{
  "title": "Elasticsearch Full-text Search",
  "content": "บทความนี้จะสอนการสร้างระบบค้นหาอัจฉริยะด้วย Elasticsearch Full-text Search ที่ SiamLancard.com",
  "author": "SiamLancard Team",
  "tags": ["elasticsearch", "full-text search", "search engine"],
  "publish_date": "2023-11-01T10:00:00Z",
  "views": 1500
}

POST /articles/_doc/2
{
  "title": "เทคนิคการปรับจูนประสิทธิภาพ Elasticsearch",
  "content": "การปรับจูน Elasticsearch เพื่อให้ได้ประสิทธิภาพสูงสุดเป็นสิ่งสำคัญมากสำหรับระบบขนาดใหญ่ เราจะมาดูเทคนิคต่าง ๆ กันครับ",
  "author": "DevOps Expert",
  "tags": ["elasticsearch", "performance", "tuning", "devops"],
  "publish_date": "2023-11-15T14:30:00Z",
  "views": 800
}

POST /articles/_doc/3
{
  "title": "การใช้ Kibana เพื่อวิเคราะห์ Log",
  "content": "Kibana ไม่ได้เป็นแค่ UI ธรรมดา แต่เป็นเครื่องมืออันทรงพลังในการวิเคราะห์ Log และสร้าง Dashboard ที่มีประโยชน์อย่างมาก",
  "author": "Data Analyst",
  "tags": ["kibana", "log analysis", "dashboard", "visualization"],
  "publish_date": "2023-10-20T09:00:00Z",
  "views": 2300
}

POST /articles/_doc/4
{
  "title": "SiamLancard บริการดูแลระบบและให้คำปรึกษา",
  "content": "SiamLancard.com ให้บริการติดตั้ง ดูแล และให้คำปรึกษาด้านระบบ IT และ Cloud Solutions สำหรับองค์กรและธุรกิจทุกขนาด",
  "author": "SiamLancard Team",
  "tags": ["siamlancard", "it services", "cloud solutions", "consulting"],
  "publish_date": "2023-12-01T11:00:00Z",
  "views": 500
}

POST /articles/_doc/{id} คือการเพิ่มเอกสารใหม่พร้อม ID ที่เรากำหนดเอง หรือใช้ POST /articles/_doc/ เพื่อให้ Elasticsearch สร้าง ID ให้โดยอัตโนมัติครับ

6. สร้างระบบค้นหาอัจฉริยะด้วย ElasticSearch Query DSL

หัวใจสำคัญของการค้นหาใน Elasticsearch คือ Query DSL (Domain Specific Language) ซึ่งเป็นภาษา JSON ที่ใช้ในการสร้างคำค้นหาที่ซับซ้อนและทรงพลังครับ

6.1. Basic Search Queries

เรามาเริ่มต้นจาก Query พื้นฐานกันก่อนครับ

  • match_all query: ค้นหาเอกสารทั้งหมดใน Index
  • GET /articles/_search
    {
      "query": {
        "match_all": {}
      }
    }
    
  • match query: ค้นหาข้อความใน Field ที่ถูก Analyze (text type)
  • GET /articles/_search
    {
      "query": {
        "match": {
          "content": "ระบบค้นหา"
        }
      }
    }
    
  • multi_match query: ค้นหาข้อความในหลาย ๆ Field พร้อมกัน
  • GET /articles/_search
    {
      "query": {
        "multi_match": {
          "query": "Elasticsearch",
          "fields": ["title", "content"]
        }
      }
    }
    
  • term query: ค้นหาคำที่ตรงกันแบบ Exact Match (ไม่ผ่าน Analyzer) เหมาะสำหรับ Field ประเภท keyword
  • GET /articles/_search
    {
      "query": {
        "term": {
          "author.keyword": "SiamLancard Team"
        }
      }
    }
    
  • range query: ค้นหาข้อมูลในช่วงที่กำหนด (ตัวเลข, วันที่)
  • GET /articles/_search
    {
      "query": {
        "range": {
          "views": {
            "gte": 1000,
            "lte": 2000
          }
        }
      }
    }
    

6.2. Advanced Search Techniques

นี่คือจุดที่ Elasticsearch เริ่มแสดงพลังที่แท้จริงครับ

  • Phrase Search (การค้นหาตามวลี):
    • ใช้ match_phrase query เพื่อค้นหาคำหลาย ๆ คำที่อยู่ติดกันในลำดับที่ถูกต้อง
    • มีประโยชน์มากในการค้นหาวลีหรือประโยคที่เฉพาะเจาะจง
    • GET /articles/_search
      {
        "query": {
          "match_phrase": {
            "content": "ระบบค้นหาอัจฉริยะ"
          }
        }
      }
      
  • Fuzzy Search (การค้นหาแบบคลุมเครือ):
    • ช่วยให้ผู้ใช้ค้นหาได้แม้ว่าจะสะกดคำผิดไปเล็กน้อย
    • ใช้พารามิเตอร์ fuzziness ซึ่งกำหนดจำนวน “การแก้ไข” ที่อนุญาต (Levenshtein distance)
    • GET /articles/_search
      {
        "query": {
          "match": {
            "title": {
              "query": "Elasticserch",
              "fuzziness": "AUTO"
            }
          }
        }
      }
      
  • Boolean Search (การค้นหาแบบบูลีน):
    • ใช้ bool query เพื่อรวม Query หลาย ๆ ตัวเข้าด้วยกันด้วยเงื่อนไข AND, OR, NOT
    • must: เอกสารต้องมี Query นี้ (AND)
    • should: เอกสารควรมี Query นี้ (OR)
    • must_not: เอกสารต้องไม่มี Query นี้ (NOT)
    • filter: คล้ายกับ must แต่ไม่ส่งผลต่อคะแนนความเกี่ยวข้อง (_score) เหมาะสำหรับกรองข้อมูล
    • GET /articles/_search
      {
        "query": {
          "bool": {
            "must": [
              { "match": { "content": "Elasticsearch" } }
            ],
            "should": [
              { "match": { "tags": "performance" } },
              { "match": { "author": "SiamLancard Team" } }
            ],
            "must_not": [
              { "match": { "tags": "kibana" } }
            ],
            "filter": [
              { "range": { "views": { "gte": 500 } } }
            ]
          }
        }
      }
      
  • Boosting (การให้คะแนนพิเศษ):
    • คุณสามารถเพิ่มน้ำหนักให้กับ Query หรือ Field บางตัว เพื่อให้ผลลัพธ์จาก Query/Field นั้นมีคะแนนความเกี่ยวข้องสูงขึ้น
    • ใช้พารามิเตอร์ boost (ค่าเริ่มต้นคือ 1.0)
    • GET /articles/_search
      {
        "query": {
          "multi_match": {
            "query": "Elasticsearch",
            "fields": ["title^3", "content", "tags^2"]
          }
        }
      }
      

      ในตัวอย่างนี้ การตรงกันใน title จะมีน้ำหนักมากกว่า content 3 เท่า และ tags มีน้ำหนักมากกว่า content 2 เท่าครับ

  • Highlighting (การเน้นคำที่ตรงกัน):
    • Elasticsearch สามารถส่งคืนส่วนของข้อความในเอกสารที่ตรงกับคำค้นหา พร้อมแท็ก HTML เพื่อเน้นข้อความนั้น ๆ
    • มีประโยชน์มากในการแสดงผลลัพธ์การค้นหาบน UI
    • GET /articles/_search
      {
        "query": {
          "match": {
            "content": "ระบบค้นหาอัจฉริยะ"
          }
        },
        "highlight": {
          "fields": {
            "content": {}
          }
        }
      }
      

      ผลลัพธ์จะรวม Field highlight ที่มีข้อความพร้อมแท็ก <em> ครับ

6.3. การปรับจูน Relevance (ความเกี่ยวข้อง)

ความสามารถที่โดดเด่นของ Full-text Search คือการให้คะแนนความเกี่ยวข้อง (_score) ซึ่งเป็นตัวเลขที่บ่งบอกว่าเอกสารนั้น ๆ มีความเกี่ยวข้องกับคำค้นหามากน้อยแค่ไหน Elasticsearch ใช้ Algorithm ที่ซับซ้อน เช่น BM25 ในการคำนวณคะแนนนี้ครับ

ปัจจัยที่ส่งผลต่อ _score:

  • Term Frequency (TF): ความถี่ที่คำค้นหาปรากฏในเอกสาร
  • Inverse Document Frequency (IDF): ความหายากของคำค้นหาใน Index (คำที่หายากมีน้ำหนักมากกว่า)
  • Field Length Norm: ความยาวของ Field (Field สั้น ๆ ที่มีคำค้นหาตรงกัน มีน้ำหนักมากกว่า)
  • Boost Factor: การปรับน้ำหนัก Query หรือ Field ที่เรากำหนดเอง

คุณสามารถใช้ explain: true ใน Query เพื่อดูรายละเอียดการคำนวณ _score ได้ครับ ซึ่งมีประโยชน์มากในการปรับจูนความเกี่ยวข้อง

6.4. ตัวอย่างการใช้ Query DSL

มาดูตัวอย่าง Query ที่ซับซ้อนขึ้นอีกนิดครับ

GET /articles/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "Elasticsearch ระบบค้นหา",
            "fields": ["title^3", "content"],
            "type": "best_fields",
            "operator": "and"
          }
        }
      ],
      "filter": [
        { "range": { "publish_date": { "gte": "2023-11-01" } } }
      ],
      "should": [
        { "term": { "tags": "siamlancard" } }
      ]
    }
  },
  "sort": [
    { "_score": { "order": "desc" } },
    { "publish_date": { "order": "desc" } }
  ],
  "highlight": {
    "fields": {
      "title": {},
      "content": {}
    }
  },
  "size": 5,
  "from": 0
}

คำอธิบาย:

  • ค้นหาเอกสารที่มีคำว่า “Elasticsearch” และ “ระบบค้นหา” ทั้งใน title (ให้น้ำหนัก x3) หรือ content (operator: "and" หมายถึงต้องมีทั้งสองคำ)
  • กรองเฉพาะบทความที่เผยแพร่หลังวันที่ 1 พฤศจิกายน 2023
  • ควรมีแท็ก “siamlancard” (จะเพิ่มคะแนนแต่ไม่บังคับ)
  • จัดเรียงตามคะแนนความเกี่ยวข้อง (_score) จากมากไปน้อย และตามวันที่เผยแพร่จากใหม่ไปเก่า
  • ทำ Highlight คำที่ตรงกันใน Field title และ content
  • แสดงผลลัพธ์ 5 รายการแรก (size: 5, from: 0)

จะเห็นได้ว่า Query DSL ให้ความยืดหยุ่นอย่างมหาศาลในการสร้างเงื่อนไขการค้นหาที่ตอบโจทย์ความต้องการที่ซับซ้อนได้อย่างง่ายดายครับ

7. การทำ Aggregations: สรุปข้อมูลเชิงลึก

นอกจากความสามารถในการค้นหาข้อมูลแล้ว Elasticsearch ยังโดดเด่นในด้าน Aggregations ซึ่งเป็นเครื่องมืออันทรงพลังในการวิเคราะห์และสรุปข้อมูลเชิงลึกจากผลลัพธ์การค้นหาครับ เปรียบเสมือนการทำ Group By หรือ Faceting ในฐานข้อมูล แต่เร็วกว่าและยืดหยุ่นกว่ามาก

7.1. Aggregations คืออะไร?

Aggregations คือการประมวลผลข้อมูลที่อยู่ใน Index เพื่อสร้างรายงานสรุปหรือเมตริกต่าง ๆ ที่มีประโยชน์ เช่น

  • การนับจำนวนเอกสารตามหมวดหมู่ (Faceting)
  • การคำนวณค่าเฉลี่ยของตัวเลข
  • การหาค่าสูงสุด/ต่ำสุด
  • การสร้างกราฟแท่งตามช่วงเวลา (Histogram)

สิ่งนี้ทำให้ Elasticsearch ไม่ได้เป็นแค่ Search Engine แต่เป็นเครื่องมือสำหรับ Analytics และ Business Intelligence ได้อย่างยอดเยี่ยมครับ

7.2. ประเภทของ Aggregations

Aggregations แบ่งออกเป็นหลัก ๆ สองประเภทครับ

  1. Metric Aggregations: คำนวณค่าสถิติจาก Field ต่าง ๆ เช่น
    • sum: ผลรวม
    • avg: ค่าเฉลี่ย
    • min: ค่าน้อยที่สุด
    • max: ค่ามากที่สุด
    • cardinality: จำนวนค่าที่ไม่ซ้ำกัน
  2. Bucket Aggregations: จัดกลุ่มเอกสารออกเป็น “Buckets” หรือกลุ่มย่อย ๆ ตามเกณฑ์ที่กำหนด
    • terms: จัดกลุ่มตามค่าที่ไม่ซ้ำกันของ Field (คล้าย Group By)
    • range: จัดกลุ่มตามช่วงค่าที่กำหนด
    • date_histogram: จัดกลุ่มเอกสารตามช่วงเวลา (วัน, เดือน, ปี)
    • nested: สำหรับ Aggregation ใน Field ประเภท Nested

คุณสามารถซ้อน Aggregation เข้าไปใน Aggregation อื่น ๆ ได้เพื่อสร้างการวิเคราะห์ที่ซับซ้อนและหลากหลายครับ

7.3. ตัวอย่างการใช้ Aggregations

เรามาดูตัวอย่างการใช้งาน Aggregations จาก Index articles กันครับ

ตัวอย่างที่ 1: นับจำนวนบทความตามผู้เขียน (Terms Aggregation)

GET /articles/_search
{
  "size": 0,
  "aggs": {
    "articles_by_author": {
      "terms": {
        "field": "author.keyword",
        "size": 10
      }
    }
  }
}

คำอธิบาย:

  • "size": 0: เราไม่ต้องการผลลัพธ์การค้นหาเอกสาร แต่ต้องการเฉพาะ Aggregation
  • aggs: บล็อกสำหรับกำหนด Aggregation
  • articles_by_author: ชื่อของ Aggregation ที่เรากำหนดเอง
  • terms: ใช้ Terms Aggregation เพื่อจัดกลุ่มตามค่าที่ไม่ซ้ำกัน
  • field": "author.keyword": Field ที่ต้องการจัดกลุ่ม (ต้องเป็น keyword type)
  • "size": 10: แสดงผลลัพธ์ 10 อันดับแรก

ผลลัพธ์จะแสดงจำนวนบทความที่เขียนโดยแต่ละผู้เขียนครับ

ตัวอย่างที่ 2: นับจำนวนบทความตามแท็ก และหาค่าเฉลี่ย Views ของแต่ละแท็ก (Nested Aggregation)

GET /articles/_search
{
  "size": 0,
  "aggs": {
    "articles_by_tag": {
      "terms": {
        "field": "tags",
        "size": 10
      },
      "aggs": {
        "avg_views": {
          "avg": {
            "field": "views"
          }
        }
      }
    }
  }
}

คำอธิบาย:

  • เราซ้อน Aggregation โดยหลังจากจัดกลุ่มตาม tags แล้ว ในแต่ละกลุ่มย่อย (Bucket) เราจะคำนวณ avg_views ด้วย Metric Aggregation ประเภท avg ครับ

ตัวอย่างที่ 3: นับจำนวนบทความตามเดือนที่เผยแพร่ (Date Histogram Aggregation)

GET /articles/_search
{
  "size": 0,
  "aggs": {
    "articles_over_time": {
      "date_histogram": {
        "field": "publish_date",
        "calendar_interval": "month",
        "format": "yyyy-MM"
      }
    }
  }
}

คำอธิบาย:

  • date_histogram: จัดกลุ่มเอกสารตามช่วงเวลา
  • field": "publish_date": Field ที่เป็นประเภท Date
  • calendar_interval": "month": กำหนดช่วงเวลาเป็นรายเดือน
  • format": "yyyy-MM": กำหนดรูปแบบการแสดงผลของ Key

ผลลัพธ์จะแสดงจำนวนบทความที่เผยแพร่ในแต่ละเดือนครับ ซึ่งสามารถนำไปสร้างกราฟแสดงแนวโน้มได้ใน Kibana

Aggregations เป็นคุณสมบัติที่ทรงพลังอย่างยิ่ง ที่ทำให้ Elasticsearch กลายเป็นมากกว่าแค่ Search Engine แต่เป็น Data Store ที่พร้อมสำหรับการวิเคราะห์ข้อมูลขนาดใหญ่และรวดเร็วครับ คุณสามารถสร้าง Dashboard ที่ซับซ้อนใน Kibana โดยใช้ Aggregations เป็นข้อมูลพื้นฐานได้อย่างง่ายดาย

8. ฟีเจอร์สำคัญอื่น ๆ สำหรับระบบค้นหาอัจฉริยะ

นอกจาก Query DSL และ Aggregations แล้ว Elasticsearch ยังมีฟีเจอร์อื่น ๆ ที่จำเป็นในการสร้างระบบค้นหาที่ “อัจฉริยะ” และตอบโจทย์ผู้ใช้งานได้อย่างครบถ้วนครับ

8.1. Suggesters (Autocomplete & Spell Check)

Suggesters ช่วยเพิ่มประสบการณ์การค้นหาให้กับผู้ใช้ได้อย่างมากครับ มี 3 ประเภทหลัก ๆ

  • Term Suggester: ให้คำแนะนำสำหรับการสะกดผิดของคำเดียว คล้ายกับฟังก์ชัน Spell Check
  • Phrase Suggester: แนะนำวลีที่ถูกต้องตามบริบท โดยคำนึงถึงความถี่และลำดับของคำ
  • Completion Suggester: สำหรับ Autocomplete หรือ “Search as you type” โดยจะแนะนำคำหรือวลีที่ตรงกับที่ผู้ใช้พิมพ์ขณะนั้น

ตัวอย่าง Completion Suggester:

ก่อนอื่นต้องเพิ่ม Field completion ใน Mapping ครับ

PUT /articles/_mapping
{
  "properties": {
    "suggest_title": {
      "type": "completion"
    }
  }
}

อัปเดตเอกสารเพื่อเพิ่มข้อมูลใน Field suggest_title:

POST /articles/_update/1
{
  "doc": {
    "suggest_title": {
      "input": ["Elasticsearch Full-text Search", "Full-text Search", "Search Engine"]
    }
  }
}

จากนั้นใช้ Completion Suggester:

GET /articles/_search
{
  "suggest": {
    "article-suggest": {
      "prefix": "Elast",
      "completion": {
        "field": "suggest_title",
        "size": 5
      }
    }
  }
}

เมื่อผู้ใช้พิมพ์ “Elast” ระบบจะแนะนำ “Elasticsearch Full-text Search” เป็นต้นครับ

8.2. Synonyms (คำพ้องความหมาย)

Synonyms ช่วยให้ระบบค้นหา “ฉลาด” ขึ้น โดยสามารถเชื่อมโยงคำที่มีความหมายเดียวกันได้ แม้ว่าจะใช้คำที่แตกต่างกันครับ เช่น หากผู้ใช้ค้นหา “รถยนต์” แต่ในเอกสารมีคำว่า “รถเก๋ง” หรือ “รถกระบะ” ก็สามารถหาเจอได้

คุณสามารถกำหนด Synonym Filter ใน Analyzer ของคุณได้ครับ

PUT /products_with_synonyms
{
  "settings": {
    "analysis": {
      "filter": {
        "my_synonym_filter": {
          "type": "synonym",
          "synonyms": [
            "รถยนต์, รถเก๋ง, รถกระบะ",
            "มือถือ, โทรศัพท์มือถือ, สมาร์ทโฟน"
          ]
        }
      },
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "thai",
          "filter": ["lowercase", "my_synonym_filter"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "description": {
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}

เมื่อผู้ใช้ค้นหา “มือถือ” ระบบก็จะหาเอกสารที่มีคำว่า “โทรศัพท์มือถือ” หรือ “สมาร์ทโฟน” เจอครับ

8.3. Stop Words (คำทั่วไปที่ไม่มีนัยยะ)

Stop Words คือคำที่พบบ่อยมากในภาษา เช่น “ที่”, “ซึ่ง”, “ใน”, “และ” ในภาษาไทย หรือ “the”, “is”, “a” ในภาษาอังกฤษ ซึ่งมักจะไม่มีนัยยะสำคัญต่อความหมายของการค้นหา การลบ Stop Words ออกจาก Inverted Index จะช่วยลดขนาด Index และเพิ่มประสิทธิภาพการค้นหาได้ครับ

เราได้เห็นตัวอย่างการใช้ stop filter ใน Analyzer ไปแล้วในส่วนของ Mapping ครับ

8.4. Relevancy Tuning (การปรับจูนความเกี่ยวข้อง)

การปรับจูนความเกี่ยวข้องเป็นศิลปะและวิทยาศาสตร์ในการทำให้ผลลัพธ์การค้นหาตรงใจผู้ใช้มากที่สุดครับ นอกจาก Boosting ที่กล่าวไปแล้ว ยังมีเทคนิคอื่น ๆ อีก เช่น

  • Function Score Query: ให้คุณกำหนด Logic การคำนวณ _score ได้เองอย่างละเอียด โดยใช้ฟังก์ชันทางคณิตศาสตร์, Random Score, Field Value Factor (เช่น ให้เอกสารที่มี views สูง ๆ มีคะแนนเพิ่มขึ้น)
  • Decay Functions: ลดคะแนนความเกี่ยวข้องของเอกสารที่อยู่ห่างจากค่าที่กำหนด เช่น เอกสารที่เผยแพร่นานแล้ว หรือสินค้าที่อยู่ห่างจากตำแหน่งปัจจุบันมาก ๆ

การเข้าใจและปรับจูน Relevancy เป็นสิ่งสำคัญในการสร้างระบบค้นหาที่ผู้ใช้รู้สึกว่า “อัจฉริยะ” ครับ อ่านเพิ่มเติมเกี่ยวกับการปรับจูน Relevancy ใน Elasticsearch

9. การปรับจูนประสิทธิภาพและ Scalability

การสร้างระบบค้นหาอัจฉริยะด้วย Elasticsearch ไม่ได้จบแค่การเขียน Query ที่ซับซ้อน แต่ยังรวมถึงการทำให้ระบบทำงานได้อย่างมีประสิทธิภาพและสามารถปรับขนาดได้เมื่อข้อมูลและปริมาณการใช้งานเพิ่มขึ้นครับ

9.1. การออกแบบ Shard และ Replica Strategy

จัดส่งรวดเร็วส่งด่วนทั่วประเทศ
รับประกันสินค้าเคลมง่าย มีใบรับประกัน
ผ่อนชำระได้บัตรเครดิต 0% สูงสุด 10 เดือน
สะสมแต้ม รับส่วนลดส่วนลดและคะแนนสะสม

© 2026 SiamLancard — จำหน่ายการ์ดแลน อุปกรณ์ Server และเครื่องพิมพ์ใบเสร็จ

SiamLancard
Logo
Free Forex EA Download — XM Signal · EA Forex ฟรี
iCafeForex.com - สอนเทรด Forex | SiamCafe.net
Shopping cart