Elastic Search with Firebase

Christopher Hay-Yin Ng
3 min readNov 13, 2016

--

หลังจากที่ใช้ Firebase มาหลาย project ต้องยอมรับเลยว่า Firebase เป็น platform ที่ทรงพลังมาก ด้วยความที่มี service ต่างๆมากมาย ทำให้สามารถทำ app เบื้องต้นได้เสร็จเร็วจนตกใจ

แต่เมื่อพัฒนา app ไปถึงจุดนึงก็เริ่มติดปัญหาบางอย่างเกี่ยวกับ Realtime database นั้นคือการ search ซึ่งดูน่าจะง่าย แต่ถ้าไม่มีตัวช่วยเลยก็ยากไม่ใช่น้อย

FROM universe WHERE soulmate LIKE ‘%aoi%’

หลายท่านคงคุ้นเคยดีกับคำสั่งแบบนี้ใน SQL ที่มีไว้เพื่อค้นหาข้อมูลด้วย keyword ที่เราต้องการในสถานที่ที่เราสนใจ แต่ไม่รู้ทำไม ผมรันคำสั่งนี้มาก็นานแล้ว แต่หาอะไรไม่เจอเลย…. เศร้าจัง

สิ่งที่น่าเสียดายนั้นก็คือ เราไม่สามารถรันคำสั่งแบบนี้ได้ใน Firebase เนี่ยสิ ถึงแม้ว่า Firebase จะมีคำสั่งที่เข้าถึง reference ต่างๆได้ง่าย แต่การทำ index เองนี่คงไม่ใช่เรื่องสนุกเท่าไหร่ เพราะฉะนั้นเราต้องหาตัวช่วยนั้นก็คือ…

ElasticSearch

https://www.elastic.co/

สุดยอด search tool สุดมหัศจรรย์และแสนยืดหยุ่นตามชื่อ เจ้าตัว ElasticSearch นี่จะช่วยทำ index ให้กับข้อมูลทั้งหมดของเรา ด้วยคำสั่งง่ายๆเพียงไม่กี่บรรทัดเท่านั้น

ว่าแล้วก็มาติดตั้งกันเลยดีกว่า โดยสามารถ download ได้ที่นี้ครับ

พอแตก zip เสร็จเรียบร้อยก็ทำการเรียกคำสั่งตามข้อสอง ถ้าไม่มีอะไรผิดพลาดก็จะออกมาหน้าตาประมาณนี้ครับ

จากนั้นก็ยิง curl ไปที่ port 9200 ซะหน่อย ผลที่ได้ จะเป็น echo จาก ElasticSearch แบบนี้ครับ

{
"name" : "KjW5-MI",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "Mjfi_X3jRaSBEXPUNlifvA",
"version" : {
"number" : "5.0.0",
"build_hash" : "253032b",
"build_date" : "2016-10-26T04:37:51.531Z",
"build_snapshot" : false,
"lucene_version" : "6.2.0"
},
"tagline" : "You Know, for Search"
}

Flashlight

ถึงแม้ว่าการเขียนคำสั่งเรียกใช้งาน ElasticSearch สามารถเขียนด้วย node.js เพียงไม่กี่บรรทัด แต่ด้วยความขี้เกียจขั้นสุดของผม ผมจึงเลือกหาตัวช่วยอีกตัวมา ซึ่งก็คือ Flashlight ที่ทาง Firebase ทำไว้เพื่อเป็น plugin เชื่อม Firebase <-> ElasticSearch นั้นเอง

มีของดีอย่างนี้ จะพลาดได้ไง โคลนได้ที่นี้เลยครับ

เมื่อโคลนเสร็จแล้วจะได้ app อยู่สองส่วน นั้นคือส่วน Flashlight และตัว Example ซึ่งในตัวอย่างนั้นจะมีข้อมูล database เบื้องต้นและ security rules ไว้ให้ลองเล่นกันด้วย

Prepare Firebase

ก่อนอื่นเลยก็สร้าง Firebase project แล้วทำการ import JSON กัน

ถ้าไม่มีอะไรผิดพลาดก็จะได้ข้อมูลสวยๆแบบนี้

เสร็จแล้วก็เข้าไปแก้ไข Rules โดยก๊อปจากไฟล์ security_rules.json ไปวางทับได้เลย

ขั้นตอนสุดท้ายก่อนจะไป Flashlight กัน ก็คือการเอา private key มา เพื่อให้ server ภายนอกเข้าถึง Firebase ได้

โดยเริ่มจากการไปที่ Project settings ที่แถบ service accounts ด้านล่างจะมีให้ download private key ให้ download เก็บมาแล้ววางไว้ใน project Flashlight ที่เตรียมไว้

Configure Flashlight

เตรียม Firebase project เสร็จแล้ว ก็มาต่อที่ Flashlight โดยก่อนอื่นก็ทำการ install dependencies กันซะหน่อยด้วย npm install

เมื่อทุกอย่างราบรื่น ก็มาแก้ไขไฟล์ config.js กัน ในไฟล์นี้จะมีสองค่าคือ

  1. exports.FB_URL เป็น URL ของ Firebase
  2. exports.FB_SERVICEACCOUNT คือชื่อไฟล์ private key ที่เตรียมไว้

เมื่อแก้ไขสองค่านี้เสร็จเรียบร้อย ลองรันคำสั่ง node app.js

ซึ่งถ้าไม่มีอะไรผิดพลาด ตัว ElasticSearch จะทำการสร้าง index อย่างรวดเร็ว

จบขั้นตอน ElasticSearch มาต่อการ test ด้วยตัวอย่างใน folder example

ใน folder จะมีที่ต้องแก้ไขจุดนึงที่ไฟล์ example.js โดยเปลี่ยนค่า databaseURL เป็น URL ของเรา

var config = {
databaseURL: “<Firebase database URL>"
};

เสร็จแล้วลองรันเว็บด้วยคำสั่ง serve สำหรับใครที่ยังไม่มีสามารถลงด้วยคำสั่งนี้ครับ

npm install -g serve

เมื่อรันแล้ว จะได้หน้าตาเว็บสวยงามแบบนี้ พอลอง search ดู ก็จะเห็นว่าเราสามารถค้นหาได้จากทุก field ที่มีในระบบ มันโอ้โหสุดคูล (โดยที่เราแทบไม่ต้องทำอะไร)

พอมาดูการทำงานใน code ตรงส่วนของ doSearch(index, type, query)

function doSearch(index, type, query) {
var ref = database.ref().child(PATH);
var key = ref.child(‘request’).push({
index: index,
type: type,
query: query
}).key;
ref.child(‘response/’+key).on(‘value’, showResults);
}

จะมีค่าสามค่าที่สำคัญคือ index ที่จะกำหนดเป็นค่า ‘firebase’ ไว้ ส่วน type นั้นจะเป็น reference ที่เราจะเข้าไปค้นหา และ query คือ keyword ที่เราจะใช้

Deploy

ลองรันบน local กันเรียบร้อยแล้ว มาลองเอาขึ้น server กันดีกว่า ด้วยความขี้เกียจขั้นสุด​(อีกแล้ว) ผมเลือกที่จะใช้บริการ Heroku ซึ่งทั้งดีและฟรี และยังมี ElasticSearch ให้เล่นบนนั้นด้วย (หล่อจริงๆ)

ขั้นแรกก็ไปประกาศความเป็น heroku ที่ project Flashlight กันก่อนด้วย

heroku login
heroku create
heroku addons:add bonsai
git add .
git commit -m "Yeah!!!!! ElasticSearch"
git push heroku master
heroku ps:scale worker=1

รันจบหมดทุกคำสั่ง เราก็จะมี ElasticSearch ให้ใช้บน Heroku โดยตัว ElasticSearch สามารถเข้าผ่าน Bonsai ที่ติดตั้งเป็น add on ไว้

ภายใน Bonsai ก็จะมี UI บอกสถานะต่างๆอย่างสวยงาม ไว้ดูเพลินๆ คอยระวังไม่ให้ traffic เยอะจนเสียตังค์

เสร็จแล้ว กลับไปที่ example ของเรา เพื่อทดสอบว่ายังใช้งานได้ปกติอยู่

ก็จบเป็นที่เรียบร้อยกับการเชื่อมสัมพันธไมตรีระหว่าง Firebase และ ElasticSearch รอบหน้าถ้าไม่ขี้เกียจซะก่อน จะลองเขียน client ด้วย Android นะครับ

ขอให้มีความสุขกับการ search ครับ

--

--