stand.fmのAlgoliaを活用した検索機能の実装
(このnoteはstand.fm engineeringマガジンの記事です)
はじめに
こんにちは、stand.fm エンジニアの 外松(@toshi-toma)です。
最近、stand.fmは検索機能を大幅にアップデートしました。
stand.fmは、検索機能の実装に Algolia というSaaSを活用しています。
今回は、stand.fmにおける検索機能の実装やAlgoliaの活用について紹介したいと思います。
Algoliaとは
Algoliaとは、検索機能を提供するSaaSです。管理画面またはAPI経由で検索対象のデータをインデックス(Index)に登録すれば、Algoliaが提供するAPI経由で簡単に検索が行え、かつ検索速度も非常に高速です。
公式が提供しているECのデモサイトで、検索速度が体験できます。
また、Webの管理画面から検索対象とする属性(Attribute)の変更やランキング計算方法の調整などが簡単に行えます。
管理画面
Algoliaを用いた検索処理の流れ
検索画面
検索機能を実現するには大きくわけて、「インデックスへのデータ登録」と「キーワードをもとに検索結果を表示する」の2つの処理が必要です。
現在、stand.fmはチャンネル、ライブ、放送、ハッシュタグを対象とした検索を提供しています。
インデックスへのデータ登録
ユーザーが実際に検索を行うために、検索対象のデータをインデックスに登録する必要があります。
簡単な流れ
1. 検索対象のデータが生成されるタイミングでAlgoliaのインデックスにデータを登録
例)放送の公開、ライブの開始
2. データの変更・削除といった操作が行われるタイミングで、インデックスにあるデータを変更・削除する
例) 放送のタイトル変更、ライブの終了
登録されたデータのどの属性を検索対象とするかは別途、管理画面で設定する必要があります。
キーワードをもとに検索結果を表示する
ユーザーが検索画面でキーワードを入力したら、Algoliaで検索処理を行い、検索結果を表示します。
簡単な流れ
1. 検索キーワードが入力されたら、バックエンドのAPIを呼び出す(クライアント)
2. クライアントから受け取った検索キーワードをもとに、Algoliaに問い合わせて、検索結果を取得(バックエンド)
3. 検索にヒットしたデータのより詳細な情報をデータベースから取得してクライアントに返す(バックエンド)
4. バックエンドから受け取った検索結果を表示する(クライアント)
クライアントから直接、Algoliaに問い合わせることも可能です。しかし、再生回数やユーザーのフォロー状態といった、高頻度で更新されるデータを検索結果の表示に利用することがあるので、バックエンドを経由しています。
JavaScript APIクライアント
stand.fmはバックエンド含め、ほぼ全てのコードをJavaScriptで記述しています。前述した検索処理の中で、Algoliaに関連する部分は以下のJavaScript APIクライアントを利用しています。
※ この記事で紹介するコードはalgoliasearch v4での例です
例えば、インデックスへのデータ登録は以下のように行えます。ApplicationIDやAdminAPIKeyは管理画面から確認できます。
import algoliasearch from 'algoliasearch';
const client = algoliasearch("YourApplicationID", "YourAdminAPIKey");
const index = client.initIndex("your_index_name");
// インデックスに登録したいデータ
const data = {
id: 1,
title: "あるごりあ",
// ...
};
// インデックスに登録
index.saveObjects([data], {
autoGenerateObjectIDIfNotExist: true // ObjectIDは自動生成
});
また、インデックスに対する検索は以下のように行えます。
import algoliasearch from 'algoliasearch';
const client = algoliasearch("YourApplicationID", "YourAdminAPIKey");
const index = client.initIndex("your_index_name");
// 検索キーワード
const keyword = "あるごりあ";
// インデックスから検索結果を取得
index.search(keyword).then((res) => {
res.hits.map(v => {
console.log(v); // { id: 1, title: "あるごりあ", ... }
})
});
データの登録及び検索が非常に簡単な実装で実現できることが分かると思います。
Facetの活用
stand.fmでは、キーワード検索に加えて、Facetという機能を活用しています。
属性をFacetとして設定することで、選択した属性をカテゴリ化して絞り込んだり、Facetに対して検索することも可能です。
例えば、放送のインデックスにあるハッシュタグ(属性)をFacetとして設定することで、特定のハッシュタグに紐づいたデータの取得やハッシュタグ検索といった機能が実現できます。
Facetは、管理画面の「Attributes for faceting」から設定できます。
特定のハッシュタグ(Facet)を持つデータをインデックスから取得するには、以下のように実装できます。
const query = ""; // キーワード検索しない場合は空文字を指定
index.search(query, {
facetFilters: ["hashtags:#お笑い"],
}).then((res) => {
res.hits.map(v => {
console.log(v); // { id: 1, title: "title", hashtags: ["#お笑い"], ... }
})
});
また、インデックスに登録されているFacetの一覧は以下のように取得できます。もし、Facetに対してキーワード検索をする場合は、facetQueryを使用します。
const facetName = "hashtags"; // Facetとして設定した属性名を指定
index.searchForFacetValues(facetName).then((res) => {
res.facetHits.map(v => {
console.log(v.value, v.count); // #お笑い, 10
})
});
検索結果をより良くするための設定
Algoliaは、管理画面で色々な設定が行えます。デフォルトの設定でも十分に良い結果が得られますが、検索結果をより良くするためにいくつかの設定を加えています。
Ranking and sorting
検索結果のランキングに、デフォルトではキーワードとのマッチ度やタイポの有無などが考慮されますが、Ranking and sorting項目を設定することで、そのランキングをカスタマイズすることができます。
管理画面では、検索結果がどういった理由でその順番になっているのかも確認できるので、ランキング設定の参考になります。
ランキング情報の確認
Language
Algoliaは、デフォルトで多言語での検索をサポートしていますが、LanguageをJapaneseに設定することで、形態素解析が有効となり、より意図通りの検索結果を得ることができます。
また、LanguageをJapaneseに設定することで、 Transliteration (翻字)を有効にすることができます。これで、ひらがなで入力された検索キーワードでも、漢字やカタカナのデータにヒットするようになります。
その他
その他にも、Synonyms(同意語)や特定のクエリに対して検索結果をカスタマイズすることが可能なRulesといった設定も存在します。
さいごに
今回、stand.fmにおけるAlgoliaを活用した検索機能の実装について紹介しました。
Algoliaは非常に機能が豊富で、また試せていないレコメンド機能やinstantsearch.js というフロントエンドライブラリも提供しています。
Algoliaの詳細について詳しく知りたい場合は、Algolia Advent Calendar 2020 の記事を見るのもおすすめです。
こういった、便利な機能や設定を活用して、よりユーザーにとって使いやすい検索機能に改善していきたいと思っています。
・・・
株式会社 stand.fm では、絶賛エンジニアを募集しております!
募集職種はこちらから
Twitter で stand.fm の技術情報や note の更新をしています。
ぜひフォローしてみてください!
この記事が気に入ったらサポートをしてみませんか?