🔎

Algoliaが思った以上に凄かった話

2021/08/05に公開

オンライン家庭教師マナリンク 開発の Technote です。

最近 Algolia を利用した検索を導入したのですが、思った以上に短期間で簡単に検索機能が導入できました。

今回は Algolia を選ぶまでに検討したことや利用する際の Tips などをまとめました。

demo

要件

2種類の検索機能が要件として挙がりました。

  • 検索候補を出す機能
    • 検索窓への入力に応じてリアルタイムに科目などを検索候補として表示
  • 先生に紐づくコースを検索する機能
    • コースのタイトルと本文で全文検索し、検索にヒットしたコースを持つ先生を検索結果に表示
    • 検索にヒットしたコースも最大3件まで表示
先生A
  |- 検索にヒットしたコースA1
先生B
  |- 検索にヒットしたコースB1
  |- 検索にヒットしたコースB2
  |- 検索にヒットしたコースB3
先生C
  |- 検索にヒットしたコースC1
  |- 検索にヒットしたコースC2
 ...

どうして Algolia を選んだか

全文検索エンジンとして有名な Elasticsearch と、もともと別の機能でも使用していた Algolia が候補に挙がりました。

最終的に Algolia を選択するまでに以下のようなことを比較しました。

費用・実装コスト

Elasticsearch

Elasticsearch を選択する場合、クラウドサービスを利用するか自前でサーバを用意してOSS版を利用するなど、いくつか選択肢がありました。

  1. Elastic Cloud ($16/月〜)
  2. OSS (t2.micro に乗せる場合は $8/月程度)
  3. Amazon Elasticsearch Service (t2.micro なら $20/月程度)

OSSが安くて良さそうですが、サーバを用意して Elasticsearch を動かせるまでの作業だけでなく、導入後の管理も自前で行う必要があるため、金額以上のコストが掛かりそうだと思いました。

Algolia

リクエスト数 か Record数 が 10000 までは無料で利用できます。
10000 を超えた分は 1000 ごとに $1 の従量課金になります。

https://www.algolia.com/pricing/

  • リクエスト数

A Search request is a group of one or more search operations sent in a single exchange. Search operations are triggered when a search is performed. In autocomplete and search-as-you-type implementations, a new search request is performed on every keystroke.

リクエスト数は検索のリクエスト数で、今回の入力に応じた検索候補の検索の場合は入力のたびにカウントされるので debounce するなどの工夫をしたほうが良さそうです。

  • レコード数

Simply put, a record is an item or object that contains data that someone would search (or get recommendations) for

レコード数は検索対象のアイテムの数です。

今回の要件では検索候補の検索とコースの検索を合わせても 10000 レコード数で十分足りていました。

検索の統計

Elasticsearch では Kibana という強力な可視化ツールがあり、Elastic Cloud であれば標準で使えるようです。

Algolia は管理画面で index ごとに合計の検索数やキーワードごとの検索数、検索にヒットした回数など見ることができ、機能的には十分でした。

スクリーンショット 2021-08-05 12 56 39

情報の多さ

Google Trend で見ての通り検索ボリュームは圧倒的に Elasticsearch が多く、日本語を含めた情報も Elasticsearch が多いように感じました。

スクリーンショット 2021-08-05 13 16 22

ただ Algolia にも 公式のドキュメント があり、実装には十分でした。

また Laravel であれば全文検索を導入できる Laravel Scout で Algolia のドライバが用意されていたため、データの同期などの実装に苦労することはほとんどありませんでした。

要件を満たす検索ができるか

先生に紐づくコースを検索する機能は、検索対象はコースですが検索結果は先生ユニークで出す必要がありました。

  • コースのタイトルと本文で全文検索し、検索にヒットしたコースを持つ先生を検索結果に表示
  • 検索にヒットしたコースも最大3件まで表示
先生A
  |- 検索にヒットしたコースA1
先生B
  |- 検索にヒットしたコースB1
  |- 検索にヒットしたコースB2
  |- 検索にヒットしたコースB3
先生C
  |- 検索にヒットしたコースC1
  |- 検索にヒットしたコースC2
 ...
  • Elasticsearch

実際に試しませんでしたが Parent/Child検索 でできそうでした。

  • Algolia

distinct という設定を変えるだけで表示に必要な結果が得られました。

しかし、Algoliaからは以下のような結果が帰ってくるので、多少整形する必要がありました。

検索にヒットしたコースA1
検索にヒットしたコースB1
検索にヒットしたコースB2
検索にヒットしたコースB3
検索にヒットしたコースC1
検索にヒットしたコースC2

結論

検索の機能としてはどちらもいい感じでした。

ただ今回は弊社の検索対象のデータ数や検索ボリュームを考慮した結果 Algolia のほうが費用が抑えられそうだったので最終的に Algolia を選択しました。

Algolia と Laravel Scout のおかげで、技術選定や検索デモ作成から実装、テスト、リリースまでフロントの実装も含めて 1週間程度 で完了させることができました!

その他

ダッシュボードではクエリがどのように分解されるか見ることができます。
意図した結果にならない場合が割とあったので、そのような場合は synonym の設定が必要です。

スクリーンショット 2021-08-05 13 50 39

どうしてランクインしたのかも見ることもできます。

スクリーンショット 2021-08-05 13 52 22

細かいですが Algolia は tf-idf のようなスコアリングではなく、タイブレーキングアルゴリズム というのを使用している点も Elasticsearch と異なるので、こだわるのであれば実際の検索結果を見て比較する必要がありそうです。

マナリンク Tech Blog

Discussion