Thuta Learning
ရှာဖွေရန်
Elasticsearch
IntermediateData & Databasesbeginner

Sorting, Pagination နှင့် search_after

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Sorting, Pagination နှင့် search_after concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • နမူနာ Elasticsearch query/code ကို ကိုယ်တိုင် run ပြီး output စစ်နိုင်ရန်
  • Tutorial Platform project နှင့် production scenario တွင် မှန်ကန်စွာအသုံးချနိုင်ရန်

နားလည်ထားရမယ့် အချက်

Elasticsearch search result ကို default `_score` descending order နဲ့ ပြန်ပေးပေမယ့် `sort` parameter ဖြင့် field တစ်ခု (ဥပမာ `publishedAt` descending) ပေါ်မှာ ပြန်ordering လုပ်နိုင်ပါတယ်—`sort` ကို `keyword`/numeric/date field ပေါ်မှာသာ run ရပါတယ် (`text` field ပေါ်မှာ sort ကြိုးစားရင် error/wrong order ဖြစ်တတ်ပါတယ်)။ Pagination အတွက် `from` (skip ရမယ့် document count) + `size` (ပြန်ပေးမယ့် count) ဖြင့် page 1, 2, 3 လိုမျိုး navigate လုပ်လို့ရပေမယ့် internal implementation ကတော့ shard တစ်ခုစီက `from + size` document ကို sort လုပ်ပြီး coordinating node ဆီ ပြန်ပို့ရပြီး coordinator ကနေ merge/re-sort လုပ်ရပါတယ်—`from` value ကြီးလာလေ (page 10,000 လို deep page) memory/CPU cost တက်လေဖြစ်ပြီး Elasticsearch ရဲ့ default `index.max_result_window` (10,000) ကို ကျော်ရင် error ပါ ဖြစ်တတ်ပါတယ်။ `search_after` ကတော့ ဒီပြဿနာကို ဖြေရှင်းပေးပါတယ်—page နံပါတ်ကို jump လုပ်မယ့်အစား "နောက်ဆုံး document ရဲ့ sort values ကို ကနေဆက်ပါ" ဆိုတဲ့ cursor-based approach ဖြစ်ပြီး shard တစ်ခုစီက full re-sort မလုပ်တော့ဘဲ cursor position နောက်ကနေတစ်ဆင့် ဆက်ရှာပေးရုံသာ လိုအပ်ပါတယ်။ ဒါဟာ Redis course ရဲ့ pagination lesson (offset vs cursor) နဲ့ တိုက်ရိုက် ဆင်တူပါတယ်—`from`/`size` ဟာ database ရဲ့ `OFFSET`/`LIMIT` နဲ့ တူပြီး `search_after` ကတော့ cursor-based pagination နှင့် concept တူပါတယ်—social media feed ရဲ့ "scroll ဆက်ရင် နောက်ထပ် post ဆက်ပေါ်" pattern နဲ့ ဆင်တူပါတယ်—page number ကို jump မလုပ်ဘဲ "ဒီနေရာကနေ ဆက်ပေးပါ" ဆိုတဲ့ pointer ချည်းပဲ ဆက်ပို့ရတာပါ။

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

Tutorial Platform ရဲ့ search result list ကို `publishedAt` descending order နဲ့ sort ချမယ်—admin UI ရဲ့ "page 1, page 2" navigation အတွက် `from`/`size` ကို first 10 pages (result 100 ခု) အထိတော့ သုံးလို့ရပါတယ်။ Public-facing "infinite scroll" search UI ကတော့ user သည် keyword "redis" ကနေ hundreds of results အထိ scroll ဆက်နိုင်လို့ deep pagination limit ကို လွယ်လွယ်ကူကူ ကျော်နိုင်ပါတယ်—ဒီအတွက် `search_after` ကို `publishedAt` + tie-breaker အနေနဲ့ `_id` (unique field) ကို sort key နှစ်ခုတွဲသုံးပြီး implement မယ်—tie-breaker မထည့်ရင် `publishedAt` တူညီတဲ့ documents များ page boundary မှာ duplicate/skip ဖြစ်နိုင်ပါတယ်။

အတူတူ စမ်းရေးကြည့်မယ်

http
GET /tutorials/_search
{
  "size": 10,
  "query": { "match": { "body": "redis" } },
  "sort": [
    { "publishedAt": "desc" },
    { "_id": "asc" }
  ],
  "search_after": ["2026-08-01T00:00:00Z", "tutorial-42"]
}
You should see
Previous page ရဲ့ နောက်ဆုံး document ရဲ့ sort values ကို cursor အဖြစ်သုံးပြီး "redis" search results ရဲ့ page နောက်ထပ်တစ်ခု ရမည်။

၅ မိနစ် စမ်းကြည့်

`lessonCount` descending, `_id` ascending (tie-breaker) ဖြင့် sort လုပ်ထားသော `search_after` query တစ်ခုရေးပြီး၊ `from: 50000, size: 10` ဖြင့် request တူညီတစ်ခု run ကြည့်ရင် ဘာဖြစ်နိုင်လဲ ခန့်မှန်းရေးပါ။

သတိလေးတစ်ချက်

`from`/`size` ကို deep pagination (ဥပမာ page 500+) အတွက်ပါ scaling ကောင်းမယ်လို့ ယူဆပြီး `max_result_window` limit ကို မကြိုတွက်ဘဲ production UI ဒီဇိုင်းလုပ်ခြင်း—large `from` values မှာ error/high latency ဖြစ်နိုင်ပါတယ်။

`search_after` ကို tie-breaker field (unique value ရှိတဲ့ field) မပါဘဲ sort key တစ်ခုတည်း (ဥပမာ `publishedAt` ချည်းသာ) နဲ့ implement ခြင်း—value တူညီတဲ့ documents များ page boundary မှာ duplicate/skip ဖြစ်နိုင်ပါတယ်။

Elasticsearch Guide — Paginate Search ResultsElastic

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • `from`/`size` ကို deep pagination (ဥပမာ page 500+) အတွက်ပါ scaling ကောင်းမယ်လို့ ယူဆပြီး `max_result_window` limit ကို မကြိုတွက်ဘဲ production UI ဒီဇိုင်းလုပ်ခြင်း—large `from` values မှာ error/high latency ဖြစ်နိုင်ပါတယ်။
  • `search_after` ကို tie-breaker field (unique value ရှိတဲ့ field) မပါဘဲ sort key တစ်ခုတည်း (ဥပမာ `publishedAt` ချည်းသာ) နဲ့ implement ခြင်း—value တူညီတဲ့ documents များ page boundary မှာ duplicate/skip ဖြစ်နိုင်ပါတယ်။
  • နမူနာ query/mutation ကို production cluster ပေါ် တိုက်ရိုက်မစမ်းဘဲ local/test instance နှင့် recoverable data ပေါ်တွင် အရင်အတည်ပြုပါ။

လေ့ကျင့်ခန်း

`lessonCount` descending, `_id` ascending (tie-breaker) ဖြင့် sort လုပ်ထားသော `search_after` query တစ်ခုရေးပြီး၊ `from: 50000, size: 10` ဖြင့် request တူညီတစ်ခု run ကြည့်ရင် ဘာဖြစ်နိုင်လဲ ခန့်မှန်းရေးပါ။

You'll know it worked when: Previous page ရဲ့ နောက်ဆုံး document ရဲ့ sort values ကို cursor အဖြစ်သုံးပြီး "redis" search results ရဲ့ page နောက်ထပ်တစ်ခု ရမည်။