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

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

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

สารบัญ

ทำไม Full-text Search ถึงสำคัญในยุคดิจิทัล?

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

ปัญหาของการค้นหาแบบดั้งเดิมในฐานข้อมูลเชิงสัมพันธ์ (RDBMS) โดยใช้คำสั่ง LIKE '%keyword%' คือ:

  • ประสิทธิภาพต่ำ: การค้นหาแบบนี้มักจะต้องสแกนข้อมูลทั้งตาราง ซึ่งใช้เวลามากเมื่อข้อมูลมีขนาดใหญ่
  • ไม่เข้าใจบริบท: คำสั่ง LIKE เป็นการจับคู่สตริงแบบตรงตัว ไม่สามารถเข้าใจความหมายของคำ คำพ้องความหมาย หรือจัดการกับคำผิดได้
  • ไม่มีการจัดลำดับความเกี่ยวข้อง: ผลลัพธ์ที่ได้มักจะเรียงตามลำดับที่เก็บในฐานข้อมูล ไม่ใช่ตามความเกี่ยวข้องกับคำค้นหา
  • ไม่รองรับฟีเจอร์ขั้นสูง: เช่น การแนะนำคำ (autocomplete), การกรองข้อมูล (faceting) หรือการไฮไลต์คำที่ค้นหา

Full-text Search ที่ชาญฉลาดเข้ามาแก้ไขปัญหาเหล่านี้ ด้วยความสามารถในการประมวลผลภาษาธรรมชาติ (NLP) การจัดทำดัชนีแบบพิเศษ (Inverted Index) และอัลกอริทึมการจัดลำดับความเกี่ยวข้องที่ซับซ้อน ทำให้:

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

นี่คือเหตุผลว่าทำไมการลงทุนในระบบ Full-text Search ที่มีประสิทธิภาพจึงเป็นการลงทุนที่คุ้มค่าสำหรับทุกธุรกิจในยุคดิจิทัลครับ

Elasticsearch คืออะไร? ทำไมต้องเลือกใช้?

Elasticsearch (ES) คือ Search Engine แบบ Distributed, RESTful, Real-time ที่ถูกสร้างขึ้นบน Apache Lucene ครับ มันถูกออกแบบมาเพื่อจัดเก็บ ค้นหา และวิเคราะห์ข้อมูลในปริมาณมหาศาลได้อย่างรวดเร็วและยืดหยุ่น เดิมที ES ถูกพัฒนาขึ้นเพื่อเป็นเครื่องมือค้นหา แต่ปัจจุบันได้ถูกนำไปใช้งานอย่างแพร่หลายในด้านต่างๆ เช่น Log Analytics (ELK Stack), Metrics Monitoring, Business Analytics และแน่นอนว่า Full-text Search ครับ

คุณสมบัติเด่นของ Elasticsearch ที่ทำให้มันโดดเด่นสำหรับการสร้างระบบค้นหาอัจฉริยะคือ:

  • ความเร็วสูง: ด้วยการใช้ Inverted Index และการออกแบบที่เหมาะสมกับการค้นหาข้อความ
  • ความสามารถในการขยายขนาด (Scalability): สามารถเพิ่ม Node ใน Cluster ได้อย่างง่ายดายเพื่อรองรับข้อมูลและการค้นหาที่เพิ่มขึ้น
  • ความเกี่ยวข้อง (Relevance): มีอัลกอริทึมการจัดลำดับความเกี่ยวข้องที่ซับซ้อนและปรับแต่งได้
  • RESTful API: ใช้งานง่ายผ่าน HTTP API ทำให้สามารถรวมเข้ากับแอปพลิเคชันต่างๆ ได้อย่างราบรื่น
  • Schema-less: มีความยืดหยุ่นในการจัดเก็บข้อมูล ไม่จำเป็นต้องกำหนด Schema อย่างเข้มงวดล่วงหน้า
  • Real-time: สามารถจัดทำดัชนีและค้นหาข้อมูลที่เข้ามาใหม่ได้เกือบจะทันที

เอกสาร (Document) และดัชนี (Index)

ใน Elasticsearch ข้อมูลจะถูกจัดเก็บในรูปแบบของ เอกสาร (Document) ซึ่งเป็นหน่วยข้อมูลพื้นฐานที่อยู่ในรูปแบบ JSON ครับ แต่ละ Document จะประกอบด้วย Field และ Value เหมือนกับการเก็บข้อมูลใน Row ของตารางในฐานข้อมูลเชิงสัมพันธ์ครับ

ตัวอย่าง Document:

{
  "title": "Elasticsearch Full-text Search สร้างระบบค้นหาอัจฉริยะ",
  "author": "SiamLancard Team",
  "publish_date": "2023-10-27T10:00:00Z",
  "content": "บทความนี้จะพาคุณไปรู้จักกับ Elasticsearch และวิธีการสร้างระบบค้นหาที่ชาญฉลาด...",
  "tags": ["Elasticsearch", "Full-text Search", "SEO", "SiamLancard"]
}

เอกสารเหล่านี้จะถูกจัดกลุ่มอยู่ใน ดัชนี (Index) ครับ Index ใน Elasticsearch เปรียบเสมือนฐานข้อมูล (Database) ใน RDBMS หรือ Collection ใน MongoDB ครับ โดย Index จะทำหน้าที่เก็บชุดของ Document ที่มีความคล้ายคลึงกัน เพื่อให้สามารถค้นหาและจัดการข้อมูลได้อย่างมีประสิทธิภาพ ตัวอย่างเช่น เราอาจมี Index สำหรับบทความ, Index สำหรับสินค้า, หรือ Index สำหรับข้อมูลลูกค้าครับ

โหนด (Node), คลัสเตอร์ (Cluster), ชาร์ด (Shard) และเรพลิกา (Replica)

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

  • โหนด (Node): คือ Instance ของ Elasticsearch ที่ทำงานอยู่บน Server หนึ่งๆ ครับ Node แต่ละตัวสามารถมีบทบาทที่แตกต่างกันไป เช่น Master Node, Data Node, Ingest Node หรือ Coordinating Node
  • คลัสเตอร์ (Cluster): คือกลุ่มของ Node ตั้งแต่หนึ่ง Node ขึ้นไปที่ทำงานร่วมกันเพื่อจัดเก็บและจัดการข้อมูลทั้งหมดครับ Cluster จะมีความสามารถในการขยายขนาดและมีความทนทานต่อความผิดพลาดสูง
  • ชาร์ด (Shard): เนื่องจาก Index อาจมีขนาดใหญ่มากจนไม่สามารถเก็บไว้ใน Node เดียวได้ Elasticsearch จึงแบ่ง Index ออกเป็นส่วนย่อยๆ ที่เรียกว่า Primary Shard ครับ แต่ละ Shard เป็น Lucene Index ที่ทำงานได้อย่างอิสระ สามารถกระจายไปเก็บไว้บน Node ต่างๆ ใน Cluster ได้ ทำให้สามารถประมวลผลแบบขนาน (Parallel Processing) และเพิ่มประสิทธิภาพในการค้นหา
  • เรพลิกา (Replica): เพื่อเพิ่มความทนทานต่อความผิดพลาด (Fault Tolerance) และเพิ่มประสิทธิภาพในการค้นหา (Read Scalability) Elasticsearch จะสร้างสำเนาของ Primary Shard ที่เรียกว่า Replica Shard ครับ Replica Shard จะถูกเก็บไว้ใน Node ที่แตกต่างจาก Primary Shard ของมัน หาก Primary Shard เกิดล้มเหลว Replica Shard จะถูกโปรโมทขึ้นมาเป็น Primary Shard โดยอัตโนมัติ ทำให้ระบบยังคงทำงานได้ต่อเนื่องครับ

ข้อดีของการใช้ Elasticsearch สำหรับ Full-text Search

สรุปข้อดีที่ทำให้ Elasticsearch เป็นตัวเลือกที่ยอดเยี่ยมสำหรับ Full-text Search:

  • ความเร็วที่เหนือกว่า: ด้วย Inverted Index และการทำงานแบบ Distributed ทำให้ค้นหาข้อมูลได้เร็วมาก แม้ในชุดข้อมูลขนาดใหญ่
  • ความสามารถในการปรับขนาด: เพิ่ม Node ได้ง่าย รองรับการเติบโตของข้อมูลและการค้นหาได้ไร้ขีดจำกัด
  • ความเกี่ยวข้องของผลลัพธ์ที่สูง: มี Score Algorithm ที่ซับซ้อนและปรับแต่งได้ ทำให้ผลลัพธ์ตรงใจผู้ใช้มากที่สุด
  • ความยืดหยุ่น: รองรับการค้นหาหลากหลายรูปแบบ เช่น Phrase Search, Fuzzy Search, Wildcard Search และการใช้ Regular Expressions
  • ฟีเจอร์ที่ครบครัน: มีคุณสมบัติขั้นสูงมากมาย เช่น Aggregations สำหรับการวิเคราะห์ข้อมูล, Suggesters สำหรับ Autocomplete, Highlighting สำหรับการเน้นคำที่ค้นหา
  • ระบบนิเวศที่แข็งแกร่ง: มี Kibana สำหรับ Visualization, Logstash และ Beats สำหรับ Data Ingestion ทำให้การจัดการข้อมูลครบวงจร

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

สถาปัตยกรรมพื้นฐานของ Elasticsearch สำหรับ Full-text Search

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

Lucene: หัวใจของ Elasticsearch

Elasticsearch ถูกสร้างขึ้นบน Apache Lucene ซึ่งเป็น Library สำหรับ Full-text Search โดยเฉพาะครับ Lucene เป็นเครื่องมือที่ทรงพลังและมีประสิทธิภาพสูงในการจัดทำดัชนี (Indexing) และค้นหา (Searching) ข้อความ Lucene ทำงานโดยสร้างโครงสร้างข้อมูลที่เรียกว่า Inverted Index ซึ่งเป็นหัวใจสำคัญของการค้นหาข้อความที่รวดเร็วครับ

Inverted Index: กลไกการค้นหาที่รวดเร็ว

ลองจินตนาการว่าคุณมีหนังสือหลายเล่ม และต้องการหาว่าคำว่า “Elasticsearch” ปรากฏในหนังสือเล่มไหนบ้าง หน้าไหนบ้าง ถ้าคุณต้องไล่อ่านหนังสือทีละหน้าก็จะใช้เวลานานมากครับ

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

ตัวอย่าง:

  • Document 1: “Elasticsearch is a powerful search engine.”
  • Document 2: “Full-text search with Elasticsearch is amazing.”

Inverted Index ที่สร้างขึ้นอาจมีลักษณะดังนี้ (หลังจากผ่านกระบวนการประมวลผลเบื้องต้น เช่น การแปลงเป็นตัวพิมพ์เล็ก การแยกคำ):

Term (คำ) Documents (เอกสารที่พบ)
amazing Doc 2
engine Doc 1
elasticsearch Doc 1, Doc 2
full-text Doc 2
is Doc 1, Doc 2
powerful Doc 1
search Doc 1, Doc 2
with Doc 2

เมื่อมีคำค้นหาเข้ามา เช่น “powerful search” Elasticsearch จะไม่สแกนเอกสารทั้งหมด แต่จะไปดูที่ Inverted Index ทันทีว่าคำว่า “powerful” อยู่ใน Doc 1 และ “search” อยู่ใน Doc 1 และ Doc 2 จากนั้นจึงนำผลลัพธ์มาประมวลผลต่อเพื่อหาเอกสารที่ตรงกัน ซึ่งทำได้เร็วกว่าการสแกนข้อมูลแบบเดิมหลายเท่าตัวครับ

Analyzers: การเตรียมข้อมูลก่อนการจัดทำดัชนี

ก่อนที่ข้อมูลข้อความจะถูกเก็บลงใน Inverted Index มันจะต้องผ่านกระบวนการประมวลผลที่เรียกว่า Analysis ครับ กระบวนการนี้ดำเนินการโดย Analyzer ซึ่งประกอบด้วยองค์ประกอบสามส่วนหลัก:

Character Filters

Character Filters จะทำงานก่อนเป็นอันดับแรก มีหน้าที่ในการปรับเปลี่ยนสตริงข้อความดิบ (Raw String) ก่อนที่จะถูกส่งไปยัง Tokenizer ตัวอย่างเช่น การลบ HTML Tags, การแทนที่อักขระพิเศษ หรือการแปลงตัวอักษรเป็นตัวพิมพ์เล็ก-ใหญ่ครับ

Tokenizer

Tokenizer มีหน้าที่ในการแบ่งสตริงข้อความที่ผ่าน Character Filters มาแล้ว ให้เป็นหน่วยย่อยๆ ที่เรียกว่า Tokens หรือ Terms ครับ Tokenizer ที่พบบ่อยคือ Standard Tokenizer ซึ่งจะแบ่งข้อความตามช่องว่างและเครื่องหมายวรรคตอน

ตัวอย่าง: ข้อความ “Quick brown fox!” จะถูกแบ่งเป็น Tokens: [“Quick”, “brown”, “fox”]

Token Filters

หลังจาก Tokenizer สร้าง Tokens แล้ว Token Filters จะเข้ามาประมวลผล Tokens เหล่านี้อีกครั้งครับ มีหน้าที่ในการปรับเปลี่ยน เพิ่ม หรือลบ Tokens ตัวอย่างเช่น:

  • Lowercase Token Filter: แปลง Tokens ทั้งหมดให้เป็นตัวพิมพ์เล็ก (เช่น “Quick” -> “quick”)
  • Stop Word Token Filter: ลบคำทั่วไปที่ไม่ค่อยมีความหมายในการค้นหาออก (เช่น “is”, “a”, “the”)
  • Stemming Token Filter: ลดรูปคำให้เหลือแต่รากศัพท์ (เช่น “running” -> “run”, “searches” -> “search”)
  • Synonym Token Filter: แทนที่คำด้วยคำพ้องความหมาย (เช่น “quick” -> “fast”)

การใช้ Analyzers ที่เหมาะสมเป็นสิ่งสำคัญมากในการสร้างระบบค้นหาที่มีประสิทธิภาพและแม่นยำครับ โดยเฉพาะอย่างยิ่งสำหรับภาษาที่มีโครงสร้างซับซ้อนอย่างภาษาไทย ที่ต้องใช้ Thai Tokenizer โดยเฉพาะ

Mapping: การกำหนดโครงสร้างข้อมูลและวิธีการประมวลผล

Mapping ใน Elasticsearch คือกระบวนการกำหนดว่าแต่ละ Field ใน Document ควรจะถูกจัดเก็บและประมวลผลอย่างไรครับ มันบอก Elasticsearch ว่า Field นี้มี Data Type แบบไหน (เช่น text, keyword, long, date, boolean, geo_point) และควรใช้ Analyzer ตัวใดในการประมวลผลข้อความ

ตัวอย่าง Mapping:

{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "thai_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "author": {
        "type": "keyword"
      },
      "publish_date": {
        "type": "date"
      },
      "content": {
        "type": "text",
        "analyzer": "thai_analyzer"
      },
      "tags": {
        "type": "keyword"
      }
    }
  }
}

ในตัวอย่างนี้:

  • title และ content ถูกกำหนดให้เป็น text ซึ่งหมายความว่าจะถูกวิเคราะห์ด้วย Analyzer (ในที่นี้คือ thai_analyzer) เพื่อสร้าง Inverted Index สำหรับ Full-text Search นอกจากนี้ title ยังมี sub-field ที่ชื่อ title.keyword ซึ่งเก็บค่าเป็น keyword (ไม่ถูกวิเคราะห์) เหมาะสำหรับการกรอง (filtering) หรือจัดเรียง (sorting)
  • author และ tags ถูกกำหนดให้เป็น keyword ซึ่งเหมาะสำหรับการค้นหาแบบตรงตัว การกรอง หรือการจัดกลุ่ม (aggregations)
  • publish_date ถูกกำหนดให้เป็น date เหมาะสำหรับการค้นหาตามช่วงเวลา

การกำหนด Mapping ที่ถูกต้องเป็นสิ่งสำคัญอย่างยิ่งในการสร้างระบบค้นหาที่มีประสิทธิภาพ เพราะมันส่งผลโดยตรงต่อวิธีการจัดเก็บข้อมูล, ขนาดของ Index, ความเร็วในการค้นหา และความแม่นยำของผลลัพธ์ครับ การกำหนด Mapping ที่ดีจะช่วยให้คุณสามารถใช้ประโยชน์จากคุณสมบัติของ Elasticsearch ได้อย่างเต็มที่

เริ่มต้นใช้งาน Elasticsearch: การติดตั้งและการเตรียมข้อมูล

ก่อนที่เราจะเริ่มสร้างระบบค้นหาอัจฉริยะ เราต้องมี Elasticsearch พร้อมใช้งานก่อนครับ

การติดตั้ง Elasticsearch

การติดตั้ง Elasticsearch มีหลายวิธี แต่ที่นิยมและแนะนำสำหรับผู้เริ่มต้นคือการใช้ Docker หรือการติดตั้งแบบ Binary โดยตรงครับ

วิธีที่ 1: ติดตั้งด้วย Docker (แนะนำสำหรับ Development)

ก่อนอื่นคุณต้องติดตั้ง Docker และ Docker Compose บนเครื่องของคุณก่อนครับ จากนั้นสร้างไฟล์ docker-compose.yml:

version: '7.17.6' # ใช้เวอร์ชั่นที่เข้ากันได้กับโปรเจกต์ของคุณ
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.17.6
    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:
      - es_net

  kibana:
    image: docker.elastic.co/kibana/kibana:7.17.6
    container_name: kibana
    ports:
      - 5601:5601
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    networks:
      - es_net
    depends_on:
      - elasticsearch

volumes:
  esdata:
    driver: local

networks:
  es_net:
    driver: bridge

จากนั้นรันคำสั่ง:

docker-compose up -d

Elasticsearch จะรันอยู่ที่ http://localhost:9200 และ Kibana จะรันอยู่ที่ http://localhost:5601 ครับ

วิธีที่ 2: ติดตั้งแบบ Binary (สำหรับ Production หรือ Local Development)

ดาวน์โหลดไฟล์ .zip หรือ .tar.gz จากเว็บไซต์ทางการของ Elastic (elastic.co) และทำตามขั้นตอนการติดตั้งสำหรับระบบปฏิบัติการของคุณครับ

การสร้าง Index และ Mapping เบื้องต้น

หลังจากติดตั้ง Elasticsearch แล้ว เรามาลองสร้าง Index พร้อม Mapping สำหรับบทความกันครับ ในตัวอย่างนี้ เราจะสร้าง Custom Analyzer สำหรับภาษาไทยด้วย thai_tokenizer ด้วยครับ

PUT /articles
{
  "settings": {
    "analysis": {
      "analyzer": {
        "thai_analyzer": {
          "tokenizer": "thai",
          "filter": ["lowercase"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "thai_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "content": {
        "type": "text",
        "analyzer": "thai_analyzer"
      },
      "author": {
        "type": "keyword"
      },
      "publish_date": {
        "type": "date"
      },
      "tags": {
        "type": "keyword"
      }
    }
  }
}

คำอธิบายโค้ด:

  • PUT /articles: เป็นการสร้าง Index ชื่อ articles
  • settings.analysis.analyzer.thai_analyzer: กำหนด Custom Analyzer ชื่อ thai_analyzer โดยใช้ thai tokenizer และ lowercase filter
  • mappings.properties: กำหนด Field และ Data Type รวมถึง Analyzer ที่ใช้สำหรับแต่ละ Field
  • title และ content ใช้ thai_analyzer สำหรับ Full-text Search
  • title.keyword สำหรับการค้นหาแบบตรงตัวหรือการจัดเรียง
  • author และ tags ใช้ keyword สำหรับการกรองหรือจัดกลุ่ม
  • publish_date ใช้ date สำหรับการค้นหาตามช่วงเวลา

การนำเข้าข้อมูล (Indexing Documents)

เมื่อ Index พร้อมแล้ว เราก็สามารถนำเข้า Document เข้าไปได้เลยครับ

POST /articles/_doc
{
  "title": "Elasticsearch คืออะไรและทำงานอย่างไร",
  "content": "บทความนี้อธิบายหลักการทำงานเบื้องต้นของ Elasticsearch รวมถึงแนวคิดเรื่อง Index, Document และ Shard",
  "author": "สมศักดิ์",
  "publish_date": "2023-10-20T14:30:00Z",
  "tags": ["Elasticsearch", "พื้นฐาน", "เทคโนโลยี"]
}

POST /articles/_doc
{
  "title": "เทคนิคการปรับแต่ง Query ใน Elasticsearch ให้ได้ผลลัพธ์ที่แม่นยำ",
  "content": "การเขียน Query DSL ที่มีประสิทธิภาพเป็นสิ่งสำคัญในการดึงข้อมูลที่เกี่ยวข้องจาก Elasticsearch เราจะมาดูเทคนิคต่างๆ กัน",
  "author": "สมศรี",
  "publish_date": "2023-10-25T09:00:00Z",
  "tags": ["Elasticsearch", "Query DSL", "เทคนิค"]
}

POST /articles/_doc
{
  "title": "สร้างระบบค้นหาอัจฉริยะด้วย Elasticsearch",
  "content": "เรียนรู้วิธีการใช้คุณสมบัติขั้นสูงของ Elasticsearch เช่น Aggregations และ Suggesters เพื่อสร้างประสบการณ์การค้นหาที่เหนือกว่า",
  "author": "สมศักดิ์",
  "publish_date": "2023-10-27T11:45:00Z",
  "tags": ["Elasticsearch", "Full-text Search", "AI"]
}

ตอนนี้เรามีข้อมูลอยู่ใน Elasticsearch แล้ว เราก็พร้อมที่จะเริ่มต้นการค้นหาได้เลยครับ

หัวใจของการค้นหา: Query DSL ใน Elasticsearch

การจะดึงศักยภาพสูงสุดของ Elasticsearch มาใช้ได้นั้น คุณต้องเข้าใจและเชี่ยวชาญ Query DSL (Domain Specific Language) ครับ Query DSL คือภาษา JSON ที่ใช้ในการสร้างคำสั่งค้นหาที่ซับซ้อนและยืดหยุ่น

Query DSL คืออะไร?

Query DSL เป็นเครื่องมือที่ทรงพลังที่ให้คุณสามารถกำหนดเงื่อนไขการค้นหา, การจัดลำดับความเกี่ยวข้อง, การกรองข้อมูล และคุณสมบัติอื่นๆ ได้อย่างละเอียดผ่าน JSON Object ครับ แทนที่จะใช้ภาษา SQL แบบดั้งเดิม Query DSL จะช่วยให้คุณสร้าง Query ที่สามารถปรับแต่งได้ตามความต้องการที่หลากหลายของระบบ Full-text Search

การค้นหาข้อความพื้นฐาน (Basic Full-text Queries)

เราจะเริ่มต้นด้วย Query พื้นฐานที่ใช้บ่อยที่สุดสำหรับการค้นหาข้อความครับ

Match Query

match query เป็น Full-text query มาตรฐานที่ใช้ในการค้นหาข้อความใน Field ใด Field หนึ่งครับ มันจะวิเคราะห์ข้อความค้นหา (query string) ด้วย Analyzer เดียวกันกับที่ใช้ในการจัดทำดัชนีของ Field นั้นๆ ทำให้สามารถจัดการกับคำพ้องความหมาย, stop words, หรือการลดรูปคำได้

ตัวอย่าง: ค้นหาบทความที่มีคำว่า “Elasticsearch” ใน Field title หรือ content

GET /articles/_search
{
  "query": {
    "match": {
      "title": "Elasticsearch"
    }
  }
}

ถ้าต้องการค้นหาใน content ด้วย:

GET /articles/_search
{
  "query": {
    "match": {
      "content": "ระบบค้นหา"
    }
  }
}

Match Phrase Query

match_phrase query ใช้สำหรับค้นหาวลีที่ตรงกันเป๊ะๆ (Exact Phrase) ครับ โดยคำที่อยู่ในวลีจะต้องปรากฏในลำดับเดียวกันและใกล้เคียงกันใน Field ที่ค้นหา

ตัวอย่าง: ค้นหาวลี “ระบบค้นหาอัจฉริยะ”

GET /articles/_search
{
  "query": {
    "match_phrase": {
      "title": "ระบบค้นหาอัจฉริยะ"
    }
  }
}

Query นี้จะให้ผลลัพธ์เฉพาะเอกสารที่มีวลี “ระบบค้นหาอัจฉริยะ” ปรากฏอยู่เท่านั้น ไม่ใช่แค่มีคำว่า “ระบบ” “ค้นหา” และ “อัจฉริยะ” กระจัดกระจายอยู่ครับ

Multi-Match Query

multi_match query ช่วยให้คุณสามารถค้นหาข้อความเดียวกันในหลาย Field พร้อมกันได้ ทำให้สะดวกและมีประสิทธิภาพในการค้นหาข้าม Field ครับ

ตัวอย่าง: ค้นหา “เทคนิค” ใน Field title และ content

GET /articles/_search
{
  "query": {
    "multi_match": {
      "query": "เทคนิค",
      "fields": ["title", "content"]
    }
  }
}

คุณยังสามารถกำหนด Boost ให้กับแต่ละ Field เพื่อเพิ่มความเกี่ยวข้องของ Field ที่สำคัญกว่าได้ครับ

GET /articles/_search
{
  "query": {
    "multi_match": {
      "query": "Elasticsearch Query",
      "fields": ["title^3", "content"] 
      // title ได้รับ boost 3 เท่า, content ได้รับ boost 1 เท่า
    }
  }
}

การค้นหาข้อความขั้นสูง (Advanced Full-text Queries)

Query String Query

query_string query เป็น Query ที่ทรงพลังที่อนุญาตให้คุณใช้ Lucene Query Syntax โดยตรงครับ ซึ่งรวมถึงการใช้ Boolean Operators (AND, OR, NOT), Wildcards (*, ?), Fuzzy Search (~), Proximity Search (“word1 word2″~N) และอื่นๆ อีกมากมาย เหมาะสำหรับผู้ใช้ที่ต้องการความยืดหยุ่นในการค้นหา

ตัวอย่าง: ค้นหา “Elasticsearch” และ “Query” ใน title หรือ “ระบบค้นหา” ใน content

GET /articles/_search
{
  "query": {
    "query_string": {
      "query": "(title:Elasticsearch AND title:Query) OR content:\"ระบบค้นหา\"",
      "fields": ["title", "content"]
    }
  }
}

Simple Query String Query

simple_query_string query เป็นเวอร์ชันที่เรียบง่ายกว่าของ query_string query ครับ มันจะจัดการกับ Syntax Errors ได้ดีกว่า และมีชุดของ Operator ที่จำกัดกว่า ทำให้เหมาะสำหรับรับ input จากผู้ใช้งานโดยตรง โดยไม่ต้องกังวลเรื่องการเกิด Syntax Error มากนัก

ตัวอย่าง: ค้นหา “Elasticsearch +Query -ระบบ”

GET /articles/_search
{
  "query": {
    "simple_query_string": {
      "query": "Elasticsearch +Query -ระบบ",
      "fields": ["title", "content"],
      "default_operator": "AND"
    }
  }
}

+ หมายถึงต้องมีคำนั้น, - หมายถึงต้องไม่มีคำนั้น

Common Terms Query

common_terms query ได้รับการออกแบบมาเพื่อจัดการกับคำที่พบบ่อย (common terms) และคำที่ไม่พบบ่อย (uncommon terms) แตกต่างกันไปครับ โดยทั่วไปแล้ว คำที่พบบ่อย (เช่น “the”, “is”) จะมีความสำคัญน้อยกว่าในการค้นหา คำนี้จะให้ความสำคัญกับ uncommon terms มากกว่า เพื่อปรับปรุงความเกี่ยวข้องของผลลัพธ์

ตัวอย่าง: ค้นหา “Elasticsearch และระบบค้นหา”

GET /articles/_search
{
  "query": {
    "common": {
      "content": {
        "query": "Elasticsearch และระบบค้นหา",
        "cutoff_frequency": 0.001, 
        "low_freq_operator": "AND", 
        "high_freq_operator": "OR" 
      }
    }
  }
}

cutoff_frequency กำหนดเกณฑ์ว่าคำใดเป็น common term (ความถี่สูงกว่าเกณฑ์) หรือ uncommon term (ความถี่ต่ำกว่าเกณฑ์)

การเพิ่มความเกี่ยวข้องของผลลัพธ์ (Boosting Relevance)

หนึ่งในคุณสมบัติที่ทรงพลังที่สุดของ Elasticsearch คือความสามารถในการปรับแต่งความเกี่ยวข้องของผลลัพธ์ (Relevance Scoring) ครับ Elasticsearch ใช้สูตร TF-IDF (Term Frequency-Inverse Document Frequency) และ BM25 (Best Match 25) เป็นพื้นฐานในการคำนวณ Score แต่คุณสามารถปรับแต่งได้ด้วย

การใช้ `boost` ใน Query

คุณสามารถใช้พารามิเตอร์ boost เพื่อให้น้ำหนักแก่ Field หรือ Query บางส่วนได้ครับ ค่าเริ่มต้นคือ 1.0 หากมากกว่า 1.0 จะเพิ่มความสำคัญ หากน้อยกว่า 1.0 จะลดความสำคัญ

ตัวอย่าง: ให้ความสำคัญกับ title มากกว่า content

GET /articles/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title":   { "query": "Elasticsearch", "boost": 3 }}},
        { "match": { "content": { "query": "Elasticsearch", "boost": 1 }}}
      ]
    }
  }
}

Function Score Query

function_score query เป็น Query ที่ยืดหยุ่นที่สุดในการปรับแต่ง Score ครับ มันช่วยให้คุณสามารถนำปัจจัยอื่นๆ นอกเหนือจากความเกี่ยวข้องของข้อความมาพิจารณาในการคำนวณ Score ได้ เช่น จำนวน Likes, วันที่เผยแพร่, หรือความนิยมของสินค้า

ตัวอย่าง: ค้นหา “Elasticsearch” โดยให้บทความที่ใหม่กว่ามี Score สูงกว่า

GET /articles/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "content": "Elasticsearch"
        }
      },
      "functions": [
        {
          "gauss": {
            "publish_date": {
              "origin": "now",
              "scale": "7d",
              "offset": "0d",
              "decay": 0.5
            }
          }
        }
      ],
      "boost_mode": "multiply"
    }
  }
}

ในตัวอย่างนี้ gauss function จะให้น้ำหนักกับ publish_date ที่ใกล้กับปัจจุบัน (now) มากกว่าครับ

การค้นหาแบบคลุมเครือและการแก้ไขคำผิด (Fuzzy Matching & Typo Tolerance)

ผู้ใช้งานไม่ได้พิมพ์คำค้นหาได้ถูกต้องเสมอไปครับ การจัดการกับคำผิดเป็นสิ่งสำคัญในการสร้างระบบค้นหาที่ดี Elasticsearch มีคุณสมบัติ Fuzzy Matching ที่ช่วยแก้ปัญหานี้

Fuzziness Parameter

คุณสามารถใช้พารามิเตอร์ fuzziness ใน match query เพื่ออนุญาตให้มีการสะกดคำผิดได้ในระดับหนึ่งครับ โดยใช้ Damerau-Levenshtein distance ในการคำนวณความแตกต่างระหว่างคำ

  • 0: ไม่มีการสะกดผิด
  • 1: อนุญาตให้มี 1 ตัวอักษรผิด
  • 2: อนุญาตให้มี 2 ตัวอักษรผิด
  • AUTO: Elasticsearch จะคำนวณให้เองตามความยาวของคำ (คำสั้นอนุญาตน้อยกว่า, คำยาวอนุญาตมากกว่า)

ตัวอย่าง: ค้นหาคำว่า “Easticsearch” (สะกดผิดจาก Elasticsearch)

GET /articles/_search
{
  "query": {
    "match": {
      "title": {
        "query": "Easticsearch",
        "fuzziness": "AUTO"
      }
    }
  }
}

Query นี้จะยังคงพบเอกสารที่มีคำว่า “Elasticsearch” อยู่ครับ

การค้นหาบางส่วนและการแนะนำคำ (Partial Matching & Autocomplete/Suggesters)

การแนะนำคำอัตโนมัติ (Autocomplete) หรือการค้นหาบางส่วน (Partial Matching) เป็นฟีเจอร์สำคัญที่ช่วยเพิ่มประสบการณ์ผู้ใช้งานอย่างมากครับ

Prefix Query และ Wildcard Query

  • prefix query: ค้นหาเอกสารที่มีคำที่เริ่มต้นด้วย Prefix ที่กำหนด
  • wildcard query: ค้นหาเอกสารโดยใช้ Wildcard characters (* สำหรับหลายตัวอักษร, ? สำหรับหนึ่งตัวอักษร)

ตัวอย่าง: ค้นหาคำที่ขึ้นต้นด้วย “Ela”

GET /articles/_search
{
  "query": {
    "prefix": {
      "title.keyword": "Ela"
    }
  }
}

ข้อควรระวัง: Wildcard Query อาจมีประสิทธิภาพต่ำในชุดข้อมูลขนาดใหญ่ เพราะต้องสแกน Term หลายตัว

Completion Suggester

completion suggester เป็น Suggester ที่ออกแบบมาโดยเฉพาะสำหรับ Autocomplete ครับ มันทำงานได้เร็วมากเพราะใช้โครงสร้างข้อมูลที่ปรับให้เหมาะสมกับการค้นหา Prefix

ในการใช้งาน คุณต้องเพิ่ม Field ที่มี Data Type เป็น completion ใน Mapping ก่อนครับ

เพิ่ม Field suggest_title ใน Mapping (อัปเดต Mapping ของ Index articles)

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

จากนั้น Index ข้อมูลโดยใส่ค่าใน suggest_title ด้วย:

POST /articles/_doc/1
{
  "title": "Elasticsearch คืออะไรและทำงานอย่างไร",
  "content": "...",
  "author": "สมศักดิ์",
  "publish_date": "2023-10-20T14:30:00Z",
  "tags": ["Elasticsearch", "พื้นฐาน", "เทคโนโลยี"],
  "suggest_title": {
    "input": ["Elasticsearch คืออะไร", "ทำงานอย่างไร"]
  }
}

ตัวอย่าง: ใช้ Completion Suggester เพื่อแนะนำคำ

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

Term Suggester และ Phrase Suggester

  • Term Suggester: แนะนำคำที่คล้ายกับคำที่ผู้ใช้พิมพ์ โดยพิจารณาจาก Term ที่มีอยู่ใน Index ช่วยแก้คำผิดได้
  • Phrase Suggester: แนะนำวลีที่ถูกต้อง โดยใช้โมเดลภาษาเพื่อหาว่าวลีใดมีโอกาสถูกพิมพ์มากที่สุด เหมาะสำหรับ “Did you mean?” feature

ตัวอย่าง Term Suggester:

GET /articles/_search
{
  "suggest": {
    "my-suggestion": {
      "text": "Easticsearch", 
      "term": {
        "field": "title.keyword" 
      }
    }
  }
}

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

สร้างระบบค้นหาอัจฉริยะด้วยคุณสมบัติพิเศษ

นอกเหนือจากการค้นหาข้อความพื้นฐานแล้ว Elasticsearch ยังมีคุณสมบัติพิเศษอีกมากมายที่ช่วยยกระดับระบบค้นหาของคุณให้ฉลาดและเป็นมิตรกับผู้ใช้งานมากขึ้นครับ

การไฮไลต์ผลลัพธ์ (Highlighting)

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

ตัวอย่าง: ค้นหา “ระบบค้นหา” และไฮไลต์คำใน content

GET /articles/_search
{
  "query": {
    "match": {
      "content": "ระบบค้นหา"
    }
  },
  "highlight": {
    "fields": {
      "content": {}
    },
    "pre_tags": [""],
    "post_tags": [""]
  }
}

ผลลัพธ์จะแสดง Field content พร้อมแท็ก และ คร่อมคำที่ตรงกัน เช่น “บทความนี้อธิบายหลักการทำงานเบื้องต้นของ Elasticsearch รวมถึงแนวคิดเรื่อง Index, Document และ Shard ระบบค้นหาอัจฉริยะ”

การจัดกลุ่มและกรองผลลัพธ์ (Faceting/Aggregations)

Aggregations คือคุณสมบัติที่ทรงพลังของ Elasticsearch ที่ช่วยให้คุณสามารถจัดกลุ่ม, นับ, คำนวณค่าสถิติ, และวิเคราะห์ข้อมูลได้ครับ มันถูกใช้บ่อยในการสร้าง “Facets” หรือ “Filters” สำหรับการจำกัดผลลัพธ์การค้นหา เช่น กรองตามหมวดหมู่, ช่วงราคา, หรือผู้แต่ง

Terms Aggregation

terms aggregation ใช้ในการนับจำนวนเอกสารที่ตรงกับแต่ละค่าที่ไม่ซ้ำกันใน Field ครับ เหมาะสำหรับสร้าง Filter ตามหมวดหมู่, Tags, หรือผู้แต่ง

ตัวอย่าง: นับจำนวนบทความตามผู้แต่ง (Author)

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

"size": 0 คือการบอกว่าไม่ต้องการผลลัพธ์การค้นหา (Hits) ต้องการแค่ Aggregations เท่านั้น

Range Aggregation

range aggregation ใช้ในการจัดกลุ่มเอกสารตามช่วงค่าที่กำหนดครับ เหมาะสำหรับสร้าง Filter ตามช่วงราคา, ช่วงคะแนน, หรือช่วงอายุ

ตัวอย่าง: จัดกลุ่มบทความตามปีที่เผยแพร่

GET /articles/_search
{
  "size": 0,
  "aggs": {
    "publish_year_ranges": {
      "date_range": {
        "field": "publish_date",
        "ranges": [
          { "from": "2022-01-01", "to": "2023-01-01", "key": "2022" },
          { "from": "2023-01-01", "to": "2024-01-01", "key": "2023" }
        ]
      }
    }
  }
}

Date Histogram Aggregation

date_histogram aggregation ใช้ในการจัดกลุ่มเอกสารตามช่วงเวลา เช่น รายวัน, รายสัปดาห์, รายเดือน, รายปี เหมาะสำหรับแสดงกราฟแนวโน้มข้อมูลตามช่วงเวลา

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

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

การจัดการคำพ้องความหมาย (Synonyms)

ระบบค้นหาที่ดีควรจะเข้าใจว่าคำบางคำมีความหมายเหมือนกัน หรือใกล้เคียงกันครับ เช่น “รถยนต์” กับ “รถ”, “เสื้อผ้า” กับ “เครื่องแต่งกาย” การใช้ Synonym Filter จะช่วยให้การค้นหาครอบคลุมมากขึ้น

ในการใช้งาน คุณต้องกำหนด Synonym Filter ใน Custom Analyzer ของคุณครับ

ขั้นตอนที่ 1: สร้าง Index ใหม่ (หรือปิด Index เก่าเพื่ออัปเดต Settings)

PUT /articles_v2
{
  "settings": {
    "analysis": {
      "filter": {
        "my_synonym_filter": {
          "type": "synonym",
          "synonyms": [
            "รถยนต์, รถ",
            "เสื้อผ้า, เครื่องแต่งกาย",
            "เทคโนโลยี, นวัตกรรม"
          ]
        }
      },
      "analyzer": {
        "thai_synonym_analyzer": {
          "tokenizer": "thai",
          "filter": ["lowercase", "my_synonym_filter"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "thai_synonym_analyzer"
      },
      "content": {
        "type": "text",
        "analyzer": "thai_synonym_analyzer"
      },
      "author": { "type": "keyword" },
      "publish_date": { "type": "date" },
      "tags": { "type": "keyword" }
    }
  }
}

จากนั้น Index ข้อมูลใหม่ใน articles_v2 ครับ เมื่อคุณค้นหา “รถ” ก็จะเจอเอกสารที่มี “รถยนต์” ด้วย และในทางกลับกันครับ

การจัดการ Stop Words

Stop Words คือคำทั่วไปที่ไม่มีความหมายในการค้นหามากนัก เช่น “เป็น”, “อยู่”, “คือ”, “และ” การลบ Stop Words ออกก่อนการจัดทำดัชนีจะช่วยลดขนาดของ Index และเพิ่มประสิทธิภาพการค้นหาได้ครับ

คุณสามารถใช้ stop filter ใน Custom Analyzer ได้:

PUT /articles_v3
{
  "settings": {
    "analysis": {
      "filter": {
        "my_stop_words": {
          "type": "stop",
          "stopwords": ["เป็น", "อยู่", "คือ", "และ"] 
        }
      },
      "analyzer": {
        "thai_stop_analyzer": {
          "tokenizer": "thai",
          "filter": ["lowercase", "my_stop_words"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "thai_stop_analyzer"
      },
      "content": {
        "type": "text",
        "analyzer": "thai_stop_analyzer"
      }
    }
  }
}

Custom Analyzers สำหรับภาษาไทย

ภาษาไทยมีความท้าทายในการทำ Full-text Search เนื่องจากไม่มีการเว้นวรรคระหว่างคำ (Word Boundary) เหมือนภาษาอังกฤษครับ ดังนั้นการใช้ Standard Analyzer จะไม่ให้ผลลัพธ์ที่ดี

Elasticsearch มีปลั๊กอินสำหรับภาษาไทยโดยเฉพาะ เช่น analysis-icu หรือ analysis-thai ที่มี Thai Tokenizer ซึ่งสามารถแบ่งคำภาษาไทยได้อย่างถูกต้อง

ในตัวอย่างข้างต้น เราได้ใช้ "tokenizer": "thai" ซึ่งมาจากปลั๊กอิน analysis-thai ครับ หากคุณใช้ Docker image ของ Elasticsearch ที่มาพร้อมกับปลั๊กอินนี้อยู่แล้ว หรือติดตั้งปลั๊กอินเพิ่มเติม (./bin/elasticsearch-plugin install analysis-thai) คุณก็จะสามารถใช้งาน Thai Tokenizer ได้ทันที

การสร้าง Custom Analyzer โดยรวม Character Filters, Tokenizer (เช่น Thai Tokenizer) และ Token Filters (เช่น Lowercase, Stop Words, Synonyms) เข้าด้วยกัน จะช่วยให้คุณสร้างระบบ Full-text Search สำหรับภาษาไทยที่มีประสิทธิภาพและแม่นยำสูงสุดครับ เรียนรู้เพิ่มเติมเกี่ยวกับการปรับแต่ง Analyzer

การปรับปรุงประสิทธิภาพและการปรับแต่ง (Optimization & Tuning)

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

Mapping Optimization: การเลือก Data Type ที่เหมาะสม

การกำหนด Mapping ที่ถูกต้องตั้งแต่เริ่มต้นเป็นรากฐานสำคัญของประสิทธิภาพที่ดีครับ

  • text vs keyword:
    • ใช้ text สำหรับ Field ที่ต้องการ Full-text Search (จะถูกวิเคราะห์)
    • ใช้ keyword สำหรับ Field ที่ต้องการค้นหาแบบตรงตัว, การกรอง (filter), การจัดเรียง (sort) หรือ Aggregations (จะไม่ถูกวิเคราะห์)

    หากต้องการทั้งสองอย่าง ให้ใช้ Multi-field เช่น "title": { "type": "text", "fields": { "keyword": { "type": "keyword" }}}

  • index parameter:
    • true (ค่าเริ่มต้น): Field จะถูกจัดทำดัชนีและค้นหาได้
    • false: Field จะไม่ถูกจัดทำดัชนีและค้นหาไม่ได้ (แต่ยังคงเก็บใน _source เพื่อดึงข้อมูลออกมาได้) ใช้กับ Field ที่ไม่ต้องการค้นหาเพื่อลดขนาด Index
  • doc_values:
    • เปิดใช้งานโดยค่าเริ่มต้นสำหรับ Field ประเภท keyword, numeric, date
    • ช่วยให้การจัดเรียง (sorting) และ Aggregations มีประสิทธิภาพสูง
    • ปิด doc_values หากไม่ต้องการใช้ Sorting หรือ Aggregations กับ Field นั้นๆ เพื่อลดขนาด Index และใช้หน่วยความจำน้อยลง (แต่ควรพิจารณาให้ดี)

Shard & Replica Strategy: การออกแบบโครงสร้างเพื่อประสิทธิภาพและความทนทาน

การกำหนดจำนวน Primary Shard และ Replica Shard มีผลอย่างมากต่อประสิทธิภาพและความทนทานของ Cluster ครับ

  • Primary Shards:
    • แต่ละ Primary Shard เป็น Lucene Index ที่ทำงานแยกกัน
    • จำนวน Shard ที่มากเกินไป (Over-sharding) จะเพิ่ม Overhead ในการจัดการและใช้ทรัพยากรมากเกินไป
    • จำนวน Shard ที่น้อยเกินไปอาจทำให้ไม่สามารถใช้ประโยชน์จาก Hardware ได้เต็มที่ และเป็นคอขวดเมื่อข้อมูลและ Query เพิ่มขึ้น
    • ควรเริ่มต้นด้วยจำนวน Shard ที่เหมาะสม (เช่น 1-5 Shards ต่อ Index) และเพิ่มตามความจำเป็นเมื่อข้อมูลเติบโต
    • ขนาดของ Shard ที่เหมาะสมมักจะอยู่ในช่วง 10GB – 50GB ครับ
  • Replica Shards:
    • เพิ่มความทนทานต่อความผิดพลาด (หาก Node ที่มี Primary Shard ล่ม Replica จะเข้ามาแทนที่)
    • เพิ่มความสามารถในการรองรับการอ่าน (Read Scalability) เพราะ Query สามารถรันบน Primary หรือ Replica Shard ก็ได้
    • โดยทั่วไปควรมีอย่างน้อย 1 Replica ครับ (ทำให้มีข้อมูลสำเนา 2 ชุด)

Caching: เพิ่มความเร็วในการค้นหา

Elasticsearch มี Cache หลายระดับที่ช่วยเพิ่มความเร็วในการค้นหา:

  • Node Query Cache: Cache ผลลัพธ์ของ Filter Query ที่ถูกใช้บ่อยๆ
  • Shard Request Cache: Cache ผลลัพธ์ของ Query ทั้งหมด (รวมถึง Aggregations) สำหรับ Shard ที่ไม่มีการเปลี่ยนแปลง
  • Field Data Cache: ใช้สำหรับ Aggregations และ Sorting บน Field ประเภท text ที่ไม่ได้ใช้ doc_values (ซึ่งไม่แนะนำให้ใช้)

การเข้าใจและใช้ Cache อย่างเหมาะสมจะช่วยลด Latency ในการค้นหาได้อย่างมากครับ

Heap Size: การจัดสรรหน่วยความจำ JVM

Elasticsearch รันบน Java Virtual Machine (JVM) ดังนั้นการจัดสรร Heap

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

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

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