ปัญหา

ถ้าเราต้องการ distinct ข้อมูลจาก Elasticsearch ล่ะทำได้ไหม ?

อาจจะยังงงๆ กันว่ามันคืออะไร
มาดูตัวอย่างกัน สำหรับ SQL เช่น
มีข้อมูล ชื่อ ซ้ำๆ ดังนี้
ID= 1, Name = ABC
ID= 2, Name = ABC
ID= 3, Name = XYZ

ดังนั้น ถ้าผมต้องการดึงข้อมูลโดยชื่อต้องไม่ซ้ำ
ใน SQL สามารถทำได้ดังนี้
SELECT DISTICT name FROM som_table

ผลที่ได้คือ
ABC
XYZ

แล้วใน Elasticsearch ล่ะ ทำอย่างไร ?

วิธีการแก้ไขปัญหา ?

ใน Elasticsearch มันไม่มีความสามารถนี้นะ
สามารถติดตาม feature ได้ใน ISSUE ของ Elasticsearch#256

เป็น feature ที่คนใช้งาน Apache Solr มาก่อน ต้องขอกันทุกๆ คน
ตัวอย่าง การใช้งาน grouping หรือ field collapsing ด้วย Apache Solr

จากบทความดังกล่าว ทำการ groupping ข้อมูลตามผู้แต่งหนังสือ (author) ดังรูป
Screen Shot 2558-03-28 at 12.28.56 PM

แต่ใน Elasticsearch ทำไม่ได้นะ
นั่นอาจจะเป็นสาเหตุหนึ่งที่ทำให้ไม่นำ Elasticsearch มาใช้งาน

สาเหตุที่ Elasticsearch ไม่นำ feature นี้เข้ามาด้วยคืออะไรล่ะ ?
เท่าที่ดูมา ก็คือ feature นี้มันไม่รองรับ Distributed search
ซึ่งนั่น จะขัดแย้งกับความต้องการ หรือ เป้าหมายของ Elasticsearch โดยตรง
เนื่องจาก Elasticsearch ถูกสร้างขึ้นมา เพื่อ Distributed search นั่นเอง

แต่บางคนก็บอกว่า performance ของ feature นี้
ซึ่งอยู่ใน Apache Lucene มันดีขึ้นมาเลยนะ
แล้วทำไม Elasticsearch ยังไม่เอาเข้ามาอีกล่ะ !!

แต่ก็พอทำได้ ซึ่งผมจะอธิบายวิธีการแก้ไขปัญหาดังนี้

วิธีที่ 1 สามารถใช้งานผ่าน Aggregation TopHit ดังตัวอย่าง

ผลจากการ query นั้นเป็นดังนี้

สามารถ distinct ข้อมูลได้ตามที่ต้องการ
แต่จะปัญหาในเรื่องของ paging อยู่นะครับ

วิธีที่ 2 ต้องเปลี่ยนแนวคิดใหม่
ปัญหาดังกล่าว เกิดขึ้นจาก เราคิดว่า Elasticsearch มันคือที่เก็บข้อมูลเหมือน RDBMS ทั่วไป
จากนั้นเราจึงมาทำการดึงข้อมูลตามที่ต้องการ !!
ซึ่งเป็นแนวคิดที่ไม่ถูกต้องมากนัก

เนื่องจากในการทำพวก NoSQL ต่างมาใช้งานนั้น
เราควรเริ่มต้นด้วยคำถามว่า
เรากำลังจะทำอะไร ?
เราต้องการอะไร ?
จากนั้น เราจึงเริ่มคิดว่า จะเก็บข้อมูลอะไร อย่างไรบ้าง ?
นั่นคือ Data model ที่จะเกิดขึ้น

จากปัญหาเหล่านี้ เราสามารถคิดได้หลายวิธีเช่น

  • สร้าง index (Database) หรือ type (Table) สำหรับจัดกลุ่มข้อมูลขึ้นมาก่อน ใช้สำหรับค้นหาข้อมูลเลย
  • ใน Elasticsearch มันมี Data model แบบ Parent-child ให้ใช้งานนะ
  • รวมทั้งยังไม่ Data model แบบ Nest object ให้ใช้ มันน่าจะเหมาะสมกับปัญหากว่าไหม ?

จะสังเกตุได้ว่า Data model ของ Elasticsearch มันสำคัญมากๆ ครับ
ดังนั้น ให้ตั้งคำถาม ก่อนที่เริ่มเก็บข้อมูลครับ