#ปัญหา: PostgreSQL ไม่รู้จักคำว่า "คำ" ในภาษาไทย

full-text search ของ PostgreSQL ทำงานบนสมมติฐานว่าข้อความมีช่องว่างคั่นระหว่างคำ ซึ่งภาษาไทยไม่มี ผลคือ to_tsvector('simple', 'การค้นหาแบบไฮบริด') จะได้ token เดียวยาว ๆ แทนที่จะเป็น "การค้นหา" + "แบบ" + "ไฮบริด"

SELECT to_tsvector('simple', 'การค้นหาแบบไฮบริด');
-- 'การค้นหาแบบไฮบริด':1

เมื่อผู้อ่านค้นด้วยคำว่า "ไฮบริด" คำนั้นจะไม่ match กับ token ข้างบนเลย

#ทางออก: ให้ embedding รับงานภาษาไทย

embedding model ไม่ต้องตัดคำ เพราะทำงานบน subword token ที่เรียนมาจากข้อมูลจริง เราจึงใช้ semantic search เป็นตัวหลักสำหรับ query ภาษาไทย และใช้ keyword search เป็นตัวเสริมสำหรับศัพท์เทคนิคภาษาอังกฤษ เช่น pgvector หรือ wire:stream ที่ embedding มักจะ "เกลี่ย" ความหมายจนจับคู่ไม่ตรงตัว

#รวมคะแนนด้วย Reciprocal Rank Fusion

ปัญหาคือ ts_rank กับ cosine similarity อยู่คนละสเกล จะเอามาบวกกันตรง ๆ ไม่ได้ RRF แก้ด้วยการรวมจาก อันดับ แทนคะแนน

score(doc) = Σ 1 / (k + rank_i(doc)),  k = 60

วิธีนี้ไม่ต้องมีค่า weight ที่ต้อง tune ใหม่ทุกครั้งที่ corpus เปลี่ยน