Calm Hill My Random Thoughts

SQLite Full-Text Search with Myanmar Scripts

Text Index လုပ်မယ်ဆိုရင် Lucene ဟာ နာမည်ကြီးသလို တကယ်လည်း ကောင်းပါတယ် အသေအချာသုံးနိုင်မယ်ဆိုရင် TB အရွယ်အစား Data တွေအထိ Index လုပ်နိုင်သလို Query လုပ်နိုင်ပါတယ်။ ဒါပေမယ့် Lucene ရဲ့ပြဿနာက Lightweight မဟုတ်ပါဘူး ကွန်ပျူတာပေါ်မှာ အဆင်ပြေပေမယ့် Mobile Device တွေလို Computing Capacity နည်းတဲ့ Devices တွေအတွက်တော့ သိပ်အဆင်မပြေပါ။ နောက်တစ်ချက်က Project ဟာ Java နဲ့ Implement လုပ်ထားတဲ့အတွက် Java ကို အရမ်းမှီခိုတဲ့အတွက် Platform တိုင်းအတွက် အဆင်မပြေပါဘူး တစ်ခြား Language တွေကို Port လုပ်ထားတာတွေရှိပေမယ့် အဲဒီ့ပရောဂျက်တွေဟာ Active မဖြစ်တာများပါတယ်။

လတ်တလောအနေနဲ့ SQLite ဟာ Mobile Device အတော်များများမှာ အလုပ်လုပ်ပါတယ် SQLite ရဲ့ Full-Text Search ဟာလည်း လက်ခံနိုင်လောက်အောင် Functionality Powerful ဖြစ်ပါတယ်။ ကိုယ်သုံးမှာ English တစ်ခုပဲဆိုတော့ အဆင်ပြေပါတယ်။ ဒါပေမယ့် ဝါသနာအရ ဗမာစာတွေကို ထည့်ကြည့်ပြီးတော့ စမ်းကြည့်ဖြစ်တယ်။ SQLite မှာ Tokenizer က Simple, Porter, ICU ပဲပါပေမယ့် ဗမာစာအတွက်တော့ တစ်ခုမှ အသုံးမတည့်တော့မထူးပါဘူး Stemming မရနိုင်ပါဘူး ဒါပေမယ့် Query မှာ Prefix နဲ့သုံးရင်တော့ သုံးလို့အဆင်ပြေသေးတဲ့အတွက် စမ်းတော့စမ်းကြည့်ဖြစ်တယ်။

စမ်းစရာ Data ကတော့ ရှာရတာ လွယ်ပါတယ် ကိုယ့်ဘလော့ထဲက Post နည်းနည်းလောက်ကို ကူးထုတ်ပြီးတော့ စမ်းဖို့လုပ်လိုက်တယ်။ SQLite Database တစ်ခု Create လုပ်ပြီးတော့ Full-Text Search Enabled Table တစ်ခု Create လုပ်ပြီး Data တွေကို Import လုပ်လိုက်တယ်။ Query တွေမှာ ဗမာလိုပါတော့ Terminal မှာက ရေးလို့မရတာကိုတော့ ပရိုဂရမ်လည်းရေးရမှာပျင်းတာနဲ့ Query ကို File တစ်ခုထဲမှာရေး Redirect နဲ့ Pass လုပ်ပြီးထွက်လာတဲ့ Result ကိုလည်း File တစ်ခုထဲမှာသွားရေး Result File ကိုပဲဖွင့်ဖတ်လိုက်တယ်။

http://www.calmhill.com/download/blogposts.txt
$ sqlite3 blog_posts.db "CREATE VIRTUAL TABLE blog_posts USING fts4(title, content);"
$ sqlite3 blog_posts.db < blog_posts.txt
$ sqlite3 blog_posts.db < query.sql > result.txt
SELECT docid, title, snippet(blog_posts, '[', ']', '...', -1, -5) FROM blog_posts WHERE content MATCH 'ကွန်ပျူတာ';
23  | ကျောင်းတော်ကြီးသို့အလွမ်း (၁၀)| ...သင်္ချာနဲ့တွဲလျက်ပေါ့ အဲဒီတော့ [ကွန်ပျူတာ] ကျောင်းသားဆိုတာ သင်္ချာတော်ကြပါတယ်။...
25  | ပရိုဂရမ်မာဋီကာ (၂)| ...ကိုယ့်နိုင်ငံက လူမျိုးတွေတောင် [ကွန်ပျူတာ] အဟောင်းဝယ်ပါလား အကြံပေးမိရင်...

ကွန်ပျူတာ” ဆိုတဲ့ စကားလုံးပါတဲ့ Post တွေကိုရှာတော့ အဖြေက ၂ ခုထွက်ပါတယ်။ တကယ်တော့ “ကွန်ပျူတာ” ဆိုတဲ့စကားလုံးပါတဲ့ Post ကတော့ ၂ ခုထက်ပိုပါတယ် ဒါပေမယ့် SQLite ကနားလည်တဲ့ Simple Tokenizer ဟာ Space or Punctuation Character တွေနဲ့ပဲ Tokenize လုပ်တဲ့အတွက် “ကွန်ပျူတာ” ဆိုတဲ့စကားလုံးအတိုင်း အတိအကျပါမှပဲ အဖြေမှာပါလာတယ်။

SELECT docid, title, snippet(blog_posts, '[', ']', '...', -1, -5) FROM blog_posts WHERE content MATCH 'ကွန်ပျူတာ*';
6       | ကျောင်းတော်ကြီးသို့အလွမ်း (၁၁)| ...ကားမောင်းဖို့ချောဆွဲပြီး မရောက်တာကြာတဲ့ [ကွန်ပျူတာတက္ကသိုလ်ဘက်ကို] ရောက်ခဲ့ပြန်တယ်။\r...
13  | Know your values| ...Technology ကကျောင်းသားလည်း [ကွန်ပျူတာပြင်ဆိုင်က] [ကွန်ပျူတာပြင်တဲ့လူကို] အားမကျရဘူး...
14  | ပေးရန်အကြွေးလက်ကျန်| ...လက်ဘက်ရည်ဆိုင် တစ်ဆိုင်ရှာပြီးတော့ထိုင် [ကွန်ပျူတာဖွင့်ပြီး] လုပ်စရာရှိတာ ထိုင်လုပ်ပြီးအချိန်ဖြုန်း...
20  | Vim Sample Showcase| ...မှတ်မိဖို့လိုတယ် အလွတ်မရခင်တော့ [ကွန်ပျူတာကို] ဆောင့်ကန်ချင်စိတ် ပေါက်လာတတ်တာပေါ့...
....
45|Dennis MacAlistair Ritchie| ...n\nကိုယ့်အတွက်တော့ [ကွန်ပျူတာနဲ့စီးပွားရေး] လုပ်စားတာအင်မတန် တော်တယ်ဆိုပြီး...
SELECT docid, title, snippet(blog_posts, '[', ']', '...', -1, -5) FROM blog_posts WHERE content MATCH '*ကွန်ပျူတာ';
23  | ကျောင်းတော်ကြီးသို့အလွမ်း (၁၀)| ...သင်္ချာနဲ့တွဲလျက်ပေါ့ အဲဒီတော့ [ကွန်ပျူတာ] ကျောင်းသားဆိုတာ သင်္ချာတော်ကြပါတယ်။...
25  | ပရိုဂရမ်မာဋီကာ (၂)| ...ကိုယ့်နိုင်ငံက လူမျိုးတွေတောင် [ကွန်ပျူတာ] အဟောင်းဝယ်ပါလား အကြံပေးမိရင်...

အဲဒီတော့ Prefix နဲ့ “ကွန်ပျူတာ” ဆိုတော့ အဖြေ ၁၆ ခုအအထိထွက်လာတယ် ဒါပေမယ့် “ကွန်ပျူတာ” တင်မဟုတ်ပဲ “ကွန်ပျူတာမှာ”၊ “ကွန်ပျူတာကို”၊ “ကွန်ပျူတာတက္ကသိုလ်” စသည်ဖြင့် “ကွန်ပျူတာ” နဲ့ စတဲ့စကားလုံးတွေ ပါလာတယ်။ “ကွန်ပျူတာ” ဆိုတဲ့စကားလုံးနဲ့ အဆုံးသတ်တာ ရှာလို့ရမလားဆိုပြီး “ကွန်ပျူတာ” ဆိုတော့အဖြေက ၂ ခုပဲထွက်သလို Postfix မပါတဲ့ “ကွန်ပျူတာ” နဲ့ရှာတဲ့ Query နဲ့အတူတူပဲထွက် Postfix နဲ့တော့ Query အလုပ်မလုပ်ပါဘူး။

အဲဒီတော့ Prefix နဲ့ရှာလို့ရတယ် Postfix နဲ့ရှာလို့မရတော့ SQL Like နဲ့ရှာတာလောက် သုံးမရဘူးထင်စရာရှိပေမယ့် Index ရှိတဲ့အတွက် Like ထက် အများကြီးမြန်ပါတယ် Like ဟာ Text Document တစ်ခုလုံးထည့်ထားတဲ့ Column တွေပေါ်မှာ Data Size အပေါ်မူတည်ပြီးတော့ Performance နှေးလွန်းပါတယ်။ ဒါပေမယ့် ဗမာစာအတွက် Tokenizer မဟုတ်တဲ့အတွက် “ကွန်ပျူတာ” လို့ရှာရင် “ကွန်ပျူတာကို”၊ “ကွန်ပျူတာမှာ”၊ “ကွန်ပျူတာထဲမှာ” စတာမျိုးတွေ တစ်ခါတည်းမရနိုင်ဘူး Postfix ထည့်ရှာရင်တော့ ပါလာပေမယ့် “ကွန်ပျူတာ” ဆိုတဲ့စကားလုံးကိုရှာတာ “ကွန်ပျူတာတက္ကသိုလ်” ဆိုတာပါလာတာ တကယ်တော့ မသက်ဆိုင်ဘူးလို့ ယူဆလို့ရပါတယ်။ ဗမာစာလုံးတွေအတွက် Custom Tokenizer ရေးပြီးတော့ ထပ်တော့စမ်းကြည့်ဦးမယ်။