firebaseとAlgoliaを連携させて全文検索を導入する手順メモ

投稿者: | 2019年1月4日

firebaseとAlgolaを連携した全文検索のトライアルをやってみました。公式ドキュメントを読みつつ手探りで設定してみましたので手順をまとめておきます。

実装した機能概要

  • firabaseのDatabase「CloudFirestore」でデータをホスティング。
  • firabaseのFunctionsにてCloudFirestoreの特定コレクションを監視、ドキュメントが追加されるたびにAlgoliaのIndexを更新する。
  • フロントからAlgoliaのAPI呼び出し、Indexから検索結果を取得する。

firebaseとAlgoliaの連携手順

① Algolia設定

①-1 Algoliaにアカウントを登録する。

まずはアカウントを作成してください。こちらからアカウントを登録しましょう。

①-2 Algolia設定 Indexを作成する。

  1. ダッシュボードの左メニューから「indeices」を選択
  2. 「Create Index」をぽちっとしてIndexを作成してください。※Indexの名称は後で使いますのでメモ。

①-3 AlgoliaからAPIキー等を取得する

ダッシュボードの左メニューの「API Keys」からAPIキーを参照することができます。

今回使用したキーは以下の3つです。

  • Application ID
  • Search-Only API Key ⇒ フロントから検索投げるときに利用
  • Admin API Key ⇒ Cloud FunctionsからAlgoliaのIndex更新するときに利用

② Functionsの作成

参考:Firebase公式ドキュメント「全文検索」

②-1 利用パッケージのインストール

npm install --save algoliasearch

②-2 環境変数の設定

AlgoliaのAPIキーたちをFunctionsのプロジェクト内で参照する環境変数として設定します。ソースにべた書きでもいいと思うのですが公式ドキュメントでも環境変数を使用していたので、やってみました。Functionsのプロジェクトフォルダでコンソールから以下のコマンドを実行します。

firebase functions:config:set algolia.app_id=★Your APP ID★
firebase functions:config:set algolia.api_key=★Your Admin API Key★
firebase functions:config:set algolia.search_key=★Your Search-Only API Key★

この辺のコマンドの説明は以下の公式ドキュメントを参考にしました。

参考:Firebase公式ドキュメント「環境の構成」

②-3 Functionsの作成

作成したCloudFunctionsのソースは以下です。

const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp(functions.config().firebase)
const algoliasearch = require('algoliasearch')
const ALGOLIA_ID = functions.config().algolia.app_id
const ALGOLIA_ADMIN_KEY = functions.config().algolia.api_key
const ALGOLIA_SEARCH_KEY = functions.config().algolia.search_key
const ALGOLIA_INDEX_NAME = 'your index name'
const client = algoliasearch(ALGOLIA_ID, ALGOLIA_ADMIN_KEY)
// コレクションに新規レコードが追加されると起動
exports.onProductUpdated = functions.firestore.document('コレクション名/{id}').onCreate((snap, context) => {
// 新規レコードの情報をIndex用オブジェクトに格納
const data = snap.data()
// objectIDをIndexするオブジェクトに追加する
data.objectID = context.params.id
// AlgoliaへIndex
const index = client.initIndex(ALGOLIA_INDEX_NAME)
return index.saveObject(data)
})

 

こんだけです。

objectID(ドキュメントのID)をIndexするオブジェクトに追加していますが、こうしておくことで、Algoliaの返却レコードとFirebaseのドキュメントを紐づけることができますので、必ず設定してください。(ドキュメントのIDもドキュメントのオブジェクトとして返却してくれればいいのに…、私は似たような処理を色んなとこで実装しています。。)

これでコレクションに新規レコードが追加されると、追加されたレコードをAlgoliaにIndexしてくれます。公式ドキュメントで紹介されているソースをほぼそのままですので、公式ドキュメントと合わせて読んでいただけるといいかと思います。

参考:Firebase公式ドキュメント「全文検索」

Indexタイミングを新規レコード作成だけでなく、レコードのアップデートなどもIndexすることも可能です。以下にFunctionsで検知可能なFirestoreのイベントトリガがまとまっています。

参考:Firebase公式ドキュメント「Cloud Firestore トリガー」

②-4 Functionsのデプロイ

以下のコマンドでデプロイできます。

firebase deploy --only functions

③ フロントからの呼び出し(検索リクエスト)

③-1 利用パッケージのインストール

npm install --save algoliasearch

 

③-2 フロントのJSへの組込

const algoliasearch = require('algoliasearch')
const client = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_SEARCH_KEY)
const index = client.initIndex('Index NAME')
index
.search({
query: 'hogehoge'
})
.then(function(responses) {
console.log(responses.hits)
})

こんな感じでalgoliasearch の初期化と、index.searchの呼び出しを追加すればOKです。こちらも公式ドキュメントを参考にしています。

参考:Firebase公式ドキュメント「全文検索」

※公式ドキュメントでは、「index.seach」とスペルミスが…

さいごに

思ったよりも簡単に実装することができたなと思います。ただコレクションが増えるたびにFunctionsへ追加してってやってくのもしんどいなぁと思ったり。なんどもAPI呼び出しするのもお金の問題で不安もあるし、そこまで何度もIndexしなくてもいいような気もしています。例えば1時間に1回とか。この辺をコントロールするにはどうしたらいいのか見当していきたいと思います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です