Algolia with VueJS
透過 InstantSearch.js 將全文查詢的結果即時呈現
上篇 Firestore with Algolia 說明如何將資料透過從 Firestore 同步至 Algolia,本篇將繼續說明前端 VueJS 如何取得並呈現 Algolia 的即時查詢結果。
關於 Algolia
Algolia 是一個即時搜尋服務,當我們將資料匯入 Algolia 後,它會自動建立索引,讓我們可以像在搜尋引擎查詢資料一樣,針對資料文本進行搜尋。Algolia 厲害的地方在於響應極快,能夠提供毫秒級的搜尋速度,還能針對查詢結果做一些處理,例如依特定欄位排序、統計查詢結果數量、將與查詢字串匹配的內容加上 tag 標注(如下圖範例)⋯⋯等。
InstantSearch.js
InstantSearch.js 是 Algolia 的 JS API Client。透過它,我們可以輕鬆呼叫 API 進行查詢,並接收回傳回來的資料進行渲染。
Step1. Initialization
首先透過 npm 進行安裝:
$ npm install instantsearch.js
安裝後,開始初始化的設定:
const instantsearch = require('instantsearch.js');const search = instantsearch({
appId: 'Application ID',
apiKey: 'Search API Key',
indexName: 'IndexName'
});search.start();
appId、appKey、indexName 皆可從 Algolia 後台的 dashboard 取得。需注意的是:Algolia 提供的 apiKey 共有 Search API Key、Write API Key 以及 Admin API Key 三種,各有不同權限。由於前端只要顯示查詢結果,不需要寫入,更不需要刪除,因此我們使用權限最小的 Search API Key 即可。
Step2. Display results
完成安裝跟設定後,我們可以開始準備接收查詢結果,並且渲染出來。InstantSearch.js 提供許多 widget 給我們使用,其中 hits 表示資料被「擊中」(被查詢到、符合查詢條件的意思),我們使用 addWidget 加入:
<div id="hits">
<!-- Hits widget will appear here -->
</div>・・・search.addWidget(
instantsearch.widgets.hits({
container: '#hits',
templates: {
empty: 'No results',
item: '<em>Hit {{objectID}}</em>:{{{_highlightResult.name.value}}}'
}
})
);search.start();
加入 hits widget 後,每次查詢都會依結果有無套上各自的 template,並被 append 進 container。從 Algolia 回傳的資料格式為 JSON,大致如下:
// 截自 https://www.algolia.com/doc/rest-api/search/#list-indexes{
"results":[
{
"hits":[
{
"name": "Betty Jane Mccamey",
"company": "Vita Foods Inc.",
"email": "betty@mccamey.com",
"objectID": "6891Y2usk0",
"_highlightResult": {
"name": {"value": "Betty <b>Jan</b>e Mccamey", "matchLevel": "full"},
"company": {"value": "Vita Foods Inc.", "matchLevel": "none"},
"email": {"value": "betty@mccamey.com", "matchLevel": "none"}
}
}],
"page": 0,
"nbHits": 1,
"nbPages": 1,
"hitsPerPage": 20,
"processingTimeMS": 1,
"query": "van",
"params": "query=van",
"index": "index1"
},・・・}
Step3. Add a SearchBox
查詢結果的頁面做好了,接下來只要提供一個搜尋框讓使用者輸入關鍵字,便可以啟動查詢。同樣透過 addWidget 加入:
<div id="search-box">
<!-- SearchBox widget will appear here -->
</div>・・・search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-box',
placeholder: 'Search for products'
})
);search.start();
設定好後,基本的即時搜尋功能便已完成,若想要更多的功能,例如將搜尋結果分頁顯示、或是捲動時無限載入其他搜尋結果、或是先前提到的排序、統計等功能,可參考官方文件,這裡就不一一贅述。
後記
基本上,InstantSearch.js 已經幫我們處理掉很多複雜的流程,但若覺得一一加上 widget 仍稍嫌麻煩,社群上已有人把 VueJS 與 InstantSearch.js 結合,詳情可見 vue-instantsearch,只要 import 對方寫好的組件之後,填上自己的憑證資訊,即可輕鬆完成搜尋功能。
<!-- main.js -->import InstantSearch from 'vue-instantsearch'; Vue.use(InstantSearch);<!-- xxx.vue --><template>
<ais-index
app-id="Application ID"
api-key="Search API Key"
index-name="IndexName"
>
<ais-search-box></ais-search-box>
<ais-results>
<template slot-scope="{ result }">
<h2>
<ais-highlight :result="result" attribute-name="name">
</ais-highlight>
</h2>
</template>
</ais-results>
</ais-index>
</template>