Easy CMS 1.13: รองรับล้านเอกสาร
หก release หลัง 1.7 สำหรับ collection ขนาดล้านเอกสาร: cursor, ค้นภาษาไทยด้วย trigram index, HTTP caching, outbox และ search adapter
Easy CMS 1.7 ทำให้รันหลาย server ได้ หก release หลังจากนั้นเป็นเรื่องขนาด: collection ที่มี 1,000,000 เอกสาร เริ่มจาก load test ที่ขนาดนี้เพื่อดูว่าเวลาหมดไปที่ไหน และไม่มี release ไหน breaking
ล้านบทความเป็นอย่างไร
load test ทุกคืนใส่บทความ 1,000,000 รายการลง Postgres 17 แล้วส่ง request พร้อมกัน 20 ตัวจาก GitHub runner 4 core เวลา p95 บนรุ่น 1.10 เป็นดังนี้
อ่านบทความตาม id หรือ slug: 22 ms
หน้าแรกของ list: 28 ms
หน้าถัดไปด้วย cursor ลึกเข้าไปใน list: 29 ms
ค้นภาษาไทยด้วย
likeและ trigram index: 69 msบันทึกฉบับร่างพร้อมเวอร์ชัน: 89 ms
ยังมีส่วนที่ช้า และคู่มือฐานข้อมูลบอกไว้ด้วย: เปิดหน้าตามเลขหน้าลึกๆ แบบสุ่มใช้เวลาหลายวินาที และ query ภายในบล็อกก็เช่นกัน
List นับน้อยลง (1.8)
การนับล้านแถวทุกหน้าคือต้นทุนของ totalDocs ส่วน count: false (REST ?count=false) ข้ามการนับไป เหมาะกับหน้า archive และ infinite scroll และตอนนี้ยอดนับของ list เดียวกันถูกใช้ซ้ำภายใน countCacheSeconds (ค่าเริ่มต้น 5 วินาที) list ที่หลายคนเปิดจึงนับครั้งเดียวในช่วงนั้น
Cursor pagination (1.9)
const page = await cms.find('posts', { cursor: '', limit: 20 })
const next = await cms.find('posts', { cursor: page.nextCursor, limit: 20 })ทุกหน้าใช้เวลาเท่าหน้าแรกไม่ว่าจะลึกแค่ไหน และ maxPage กัน API client ไม่ให้เปิดหน้าลึกๆ ด้วยเลขหน้า ดูผลของ find
ค้นภาษาไทยด้วย trigram index (1.10)
{ name: 'title', type: 'text', index: 'trigram' }บน Postgres GIN index แบบ pg_trgm ทำให้ like หาส่วนใดก็ได้ของข้อความโดยไม่ต้องอ่านทุกแถว ทั้งภาษาไทยและอังกฤษ ที่ล้านบทความ การค้นภาษาไทยใช้ 69 ms (p95) ดูค้นด้วย like
HTTP caching สำหรับ CDN (1.11)
httpCache: { sMaxAge: 60, staleWhileRevalidate: 600, purge: (tags) => tags.forEach((tag) => revalidateTag(tag)) }การอ่านเนื้อหาที่ publish แล้วแบบ public ได้ s-maxage, ETag และ cache tag ทำให้ CDN ตอบแทนได้ การบันทึก publish หรือลบจะ purge เฉพาะ tag ที่เปลี่ยน ส่วน request ที่ login หรืออ่านฉบับร่างยังเป็น no-store ดู HTTP caching
Outbox สำหรับ after hook (1.12)
outbox: truehook, webhook และการ purge cache ถูกเขียนลงใน transaction เดียวกับการบันทึก แล้วรันหลัง commit และ retry จนสำเร็จ การบันทึกที่สำเร็จจึงได้ผลข้างเคียงครบเสมอ รายการที่ล้มแสดงใน Settings → Jobs → Outbox และ hook ต้องรันซ้ำได้โดยไม่เสียหาย ดู Outbox
Search adapter (1.13)
search: memorySearch(),
collections: [{ slug: 'posts', search: { fields: ['title', 'body'] }, /* … */ }],cms.search() และ GET /api/cms/search ค้นเอกสารที่ publish แล้วข้ามหลาย field และหลาย collection เรียงจากตรงที่สุด ตามสิทธิ์ของผู้อ่าน memorySearch() ตัดคำไทยด้วย Intl.Segmenter คำว่า น้ำท่วม จึงเจอ ข่าวน้ำท่วมกรุงเทพมหานคร เหมาะกับ dev และเว็บเล็ก ส่วน adapter ของ search engine ให้ implement SearchAdapter ดูค้นหา
การอัปเกรด
อัปเกรดทุก package พร้อมกัน ทุกอย่างปิดอยู่จนกว่าคุณจะเปิด มีเพียง outbox: true ที่ต้อง migrate
npm install @easy-cms/core@latest easy-cms@latestหน้า changelog มีทุกเวอร์ชัน