- สามารถสร้าง "Hybrid Search" ในแอปพลิเคชันได้โดยใช้ส่วนขยาย Full-Text Search (FTS5) พื้นฐานของ SQLite ร่วมกับการค้นหาเชิงความหมายของ sqlite-vec
- สามารถผสานผลลัพธ์ได้หลายวิธี เช่น ให้ความสำคัญกับคีย์เวิร์ดก่อน, จัดอันดับใหม่ตาม "semantic", หรือใช้ Reciprocal Rank Fusion
- ที่สำคัญที่สุดคือทุกอย่างรวมอยู่ใน SQLite จึงทำให้การทดลองและการทำต้นแบบทำได้ง่ายและต้นทุนต่ำ โดยไม่ต้องพึ่งบริการภายนอก
- กรณีใช้งานหลักของ
sqlite-vec และเครื่องมือค้นหาเวกเตอร์อื่น ๆ คือการเพิ่ม "การค้นหาเชิงความหมาย" ให้กับข้อมูลข้อความ
- การค้นหาแบบ Full-Text Search เพียงอย่างเดียว (การค้นหาด้วยคีย์เวิร์ด) ไม่ได้ให้ผลลัพธ์ที่ดีเสมอไป
- เมื่อค้นหา "climate change" จะไม่คืนเอกสารอย่าง "global warming"
- เมื่อใช้การค้นหาเชิงความหมาย จะสามารถค้นหาผลลัพธ์ตาม "ความหมายโดยรวม" และคืนผลลัพธ์ที่มีบริบทสมบูรณ์ยิ่งขึ้นได้
- แต่การใช้เพียง "การค้นหาเชิงความหมาย" อย่างเดียวก็อาจส่งผลเสียต่อแอปพลิเคชันได้
เดโม: พาดหัวข่าว NBC News
- ใช้ชุดข้อมูลที่มีพาดหัวมากกว่า 14,500 รายการ ตั้งแต่เดือนมกราคมถึงสิงหาคม 2024
- ข้อมูลข้อความรวมมีขนาดเพียง 4.3MB เป็นชุดข้อมูลที่เล็กมาก
การสร้างตาราง FTS5
- สร้างตารางเสมือนสำหรับ Full-Text Search ชื่อ
fts_headlines
- ประกาศคอลัมน์
headline
- กำหนดค่าออปชัน
content= และ content_rowid=
- ทำ
INSERT INTO โดยตรงจากตาราง articles หลัก
- การคิวรีตาราง FTS5 ต้องใช้เพียงคำสั่ง
SELECT เดียว
การสร้าง Vector Search ด้วย sqlite-vec
sqlite-vec มีความสามารถในการจัดเก็บเวกเตอร์และเปรียบเทียบเวกเตอร์ แต่ไม่ได้สร้าง embedding ให้เอง
- ในตัวอย่างนี้ใช้ส่วนขยาย
sqlite-lembed และ Snowflake Artic Embed 1.5 model
- ฝังข้อความด้วย
lembed() แล้วจัดเก็บไว้ในตารางเสมือน vec0
- การทำ KNN query ต้องใช้เพียงคำสั่ง
SELECT เดียว
แนวทางแบบไฮบริด 1: "คีย์เวิร์ดมาก่อน"
- คืนผลลัพธ์จาก Full-Text Search ก่อน แล้วจึงเติมส่วนที่เหลือด้วยการค้นหาเวกเตอร์
- สามารถทำได้ด้วย CTE
- รวมผลลัพธ์ด้วย
UNION ALL
แนวทางแบบไฮบริด 2: Reciprocal Rank Fusion (RRF)
- จัดอันดับผลลัพธ์จาก FTS5 และ vector match
- สามารถทำได้ด้วยคำสั่ง
SELECT เดียวและ CTE
- สามารถเปลี่ยนค่า
:weight_fts หรือ :weight_vec เพื่อปรับอันดับผลลัพธ์ FTS5/เวกเตอร์ให้ต่างกันได้
แนวทางแบบไฮบริด 3: จัดอันดับใหม่ตามความหมาย
- ทำเฉพาะการค้นหา FTS5 แต่จัดเรียงผลลัพธ์ใหม่ตามระยะห่างของเวกเตอร์
- ยังคงได้เฉพาะผลลัพธ์ที่ตรงกับคีย์เวิร์ด แต่ผลลัพธ์ที่มีความหมายสอดคล้องดีกว่าจะถูกเลื่อนขึ้นมาอยู่ด้านบน
- ช่วยแก้ข้อเสียของ BM25
ควรเลือกแนวทางไหน?
- ขึ้นอยู่กับแอปพลิเคชันและกรณีใช้งาน
- หากสร้าง search engine สำหรับกล่องจดหมายอีเมล การให้คีย์เวิร์ดมาก่อนจะเหมาะกว่า
- หากสร้าง RAG สำหรับเอกสารภายในบริษัท RRF เป็นตัวเลือกที่ดี
- หากสร้างฟีเจอร์ "โพสต์ซ้ำ" ในเว็บแอป การจัดอันดับใหม่ตามความหมายจะทำงานได้ดี
การปรับปรุงในอนาคต
- คิวรี FTS5 สามารถแสดงส่วนที่ตรงกันในเอกสารด้วย "highlight" ได้ แต่
sqlite-vec คืนเพียงระยะ L2/โคไซน์ระหว่าง query vector กับเอกสาร
- คิวรี FTS5 ยังมีความสามารถอื่น เช่น วลี, คิวรี
NEAR และ boolean operator แต่เมื่อนำไปใช้กับ vector search จะดูไม่ค่อยลงตัว
- การขยาย Hybrid Search ด้วย FTS5 +
sqlite-vec อาจยังดูไม่ลื่นไหลนัก
- ตาราง FTS5 จะค้นหาทั้งชุดข้อมูลทั้งหมดทุกครั้ง จึงไม่รองรับ metadata filtering หรือการรองรับดัชนี FTS5 เดียว
sqlite-vec ก็เช่นกัน แต่กำลังจะรองรับ partitioning และ metadata filtering ในเร็ว ๆ นี้
ความเห็นของ GN⁺
- Hybrid Search บน SQLite ดูมีประโยชน์กับแอปพลิเคชันหลากหลายประเภท เพราะทดลองและทำต้นแบบได้ง่าย จุดเด่นคือข้อมูลถูกเก็บในไฟล์เดียว, สามารถทดสอบหลายคิวรีได้ด้วยคำสั่ง
SELECT เดียว, ไม่มีค่าใช้จ่าย, ใช้งานได้กับทุกภาษาโปรแกรม และทำได้ง่ายด้วยโค้ดเพียงไม่กี่บรรทัด
- อย่างไรก็ตาม ยังมีจุดที่ต้องปรับปรุงระหว่าง FTS5 กับ
sqlite-vec อยู่บ้าง FTS5 สามารถเน้นส่วนที่ตรงกันในเอกสารได้ แต่ sqlite-vec คืนเพียงระยะห่างระหว่าง query vector กับเอกสารเท่านั้น นอกจากนี้ เมื่อใช้ความสามารถขั้นสูงของ FTS5 การนำมารวมกับ vector search อาจยังดูไม่ค่อยลงตัว
- แม้มีข้อจำกัดเหล่านี้ Hybrid Search บน SQLite ก็ยังเป็นโซลูชันที่ทรงพลัง ซึ่งช่วยดึงข้อดีของทั้งการค้นหาด้วยคีย์เวิร์ดและการค้นหาเชิงความหมายมาใช้ได้ ไม่ว่าขนาดข้อมูลหรือประเภทของแอปพลิเคชันจะเป็นแบบใด
- ในสถานการณ์ที่การสกัดข้อมูลจากข้อมูลไร้โครงสร้างและทำให้ค้นหาได้มีความสำคัญมากขึ้นเรื่อย ๆ การผสานการค้นหาด้วยคีย์เวิร์ดอย่าง FTS5 เข้ากับการค้นหาเวกเตอร์อย่าง
sqlite-vec ทำให้สามารถค้นหาได้อย่างซับซ้อนขึ้น โดยพิจารณาทั้งความตรงกันของคีย์เวิร์ดและความเกี่ยวข้องตามบริบท
- ไม่ว่าจะเป็นการเพิ่ม
sqlite-vec เข้าไปในระบบค้นหาเดิม หรือพัฒนาแอปค้นหาใหม่ ก็ควรพิจารณา Hybrid Search บน SQLite โดยเฉพาะอย่างยิ่งความสามารถในการปรับแต่ง embedding model เองได้ ซึ่งเป็นข้อได้เปรียบอย่างมาก
1 ความคิดเห็น
ในโปรเจกต์ได้ทำงานใส่และประมวลผลข้อมูลมากกว่า 1 ล้านรายการลงใน sqlite
ถ้าปริมาณข้อมูลมาก ก็น่าจะต้องใช้ SSD ที่ดีพอสมควร (เพราะใช้ SATA SSD เลยรู้สึกว่าเวลาในการประมวลผลเพิ่มขึ้นพอสมควร)