Algoliaを使うにあたり調べたこと

# 概要
全文検索のSaasであるAlgoliaを使ってみました。
本記事では使用にあたり調べたことを記載します。

Algoliaを触り始めるにあたっての参考になれば

## 用語
- Application
    - 最も大きな管理単位
    - indexの集まり
- index
    - 検索対象となるデータベース
- Object
    - index内の1件のデータ。JSON形式
- Record
    - オブジェクトとほぼ同義
- attributes
    - オブジェクト内の各フィールド(title, priceとか)

## 料金

主な料金は「検索回数」「（DBの）レコード数」で決まる。
- 検索回数
    - 検索1000回毎に0.5$
    - 月間1万回まで無料
- レコード数
    - 1000件毎に0.4$
    - 10万件まで無料 

https://www.algolia.com/pricing

:::note info
#### Q. 料金は高いのか？
A. 検索UIによる。

- ワード入力の度に検索実行されるタイプのUI
    - 検索1000回はすぐ到達する、__コスト大__
- 検索ボタンを押して実行するタイプのUI
    - 検索1000回はなかなか到達しない、__コスト小__

また、検索システム構築の初期投資は大幅に抑えることができる

:::


# 使い方
## index(検索DB）を作りたい
管理画面からCSVやJSONをアップロードするだけ、更新する時も同じ方法

https://www.algolia.com/doc/guides/sending-and-managing-data/send-and-update-your-data/how-to/importing-from-the-dashboard/

## 検索APIを作りたい
indexを作ると自動的にAPIも作られる

https://www.algolia.com/doc/rest-api/search/#tag/Search

## 検索対象を指定したい
- デフォルトではindex内の全てのattributesが検索対象になっている
- 例えば、画像URLなどを検索対象から外したい場合などに検索対象を特定attributesに指定する
- 「Configuration > Searchable attributes」から設定する

![スクリーンショット 2025-04-22 21.09.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/813353/2ac7b443-d465-42b7-8287-b87462f05308.png)

https://www.algolia.com/doc/api-reference/api-parameters/searchableAttributes/

## ソートを設定したい
「Configuration > Ranking and sorting」から設定する

設定できるソート項目には以下の種類がある（画像赤枠）
- SORT-BY
    - 厳密なソート
    - 任意のattributesを設定可能
    - TEXTUAL、CUSTOM RANKINGより優先して並べ替えられる
- TEXTUAL
    - 入力ワードにどれだけ検索対象のObjectがマッチしたかの関連度
    - 高いほど検索上位に表示される
    - 任意の項目を追加することはできない
- CUSTOM RANKING
    - TEXTUALの次に適応されるソート順
    - 任意のattributesを設定可能
    - TEXTUALのスコアが同じだった場合、CUSTOM RANKINGが適応される

![スクリーンショット 2025-04-22 21.15.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/813353/b62e1fdd-54ab-4812-810b-9b7f9a1ca498.png)

https://www.algolia.com/doc/api-reference/api-parameters/ranking/


:::note info
#### 検索結果の並び替えロジック
Algoliaはタイブレーキングという並び替え方式を使っている
イメージとしては、よくある「第１ソート」「第２ソート」と同じ考え方で合っていると思う

例えば、下記の設定だった場合、日付が同じレコードのみ価格で並べ替えられる動きになる
- 第１ソート: 日付
- 第２ソート: 価格


これは、前述のTEXTUAL（関連度）も同じで、以下設定だった場合、typo→word→exactの順で並び替えが行われる
1. typo (誤字が少ない順）
1. word (マッチしている文字が多い順）
1. exact（完全一致した単語が多い順）

参考
https://blog.tatsuroh.com/2020-12-02/algolia-ranking-explained
:::

## 絞り込み項目を設定したい
- 検索APIのfiltersパラメータを使う
- 特に事前設定は必要ない

https://www.algolia.com/doc/api-reference/api-parameters/filters/

## 件数付きのフィルターを作りたい

以下赤枠のように件数付きのフィルターを作成したいニーズがあると思う
こういったフィルターを作りやすくするために、AlgoliaにはFacetsという機能がある。


![スクリーンショット 2025-04-22 22.48.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/813353/c74fdd06-d4cb-40e9-a42c-71207f1fbb1a.png)


- 「Configuration > Facet > Attributes for faceting」からfacets登録するattributesを追加する
- Facetsに登録されたattributesは、値と件数をAPIから取得できるようになる


![スクリーンショット 2025-04-22 21.56.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/813353/5338b4af-c8a2-4700-ae6f-66d1871dc6b7.png)


### 例
indexに以下のオブジェクトを登録し
このうちのtagsをfacetsに設定したとする
``` 
[
  {
    "title": "ファイナルファンタジーX",
    "tags": ["スクエニ", ”RPG”, "PS2", ]
  },
  {
    "title": "ドラゴンクエスト7",
    "tags": ["スクエニ",　”RPG”, "PS" ]
  }
  {
    "title": "キングダム ハーツ",
    "tags": ["スクエニ", ”アクション”, "PS2", ]
  }
]
```

facetに登録したattributesは、以下のように検索APIレスポンスのfacetsに含まれるようになり
indexに存在する値とその件数が返ってくる

```
{
  "facets": {
    "tags": {
      "スクエニ": 3,
      "RPG": 2,
      "アクション": 1,
      "PS2": 2,
      "PS": 1,
    }
  },
  "hits": {...},
}

```

https://www.algolia.com/doc/api-reference/api-parameters/facets/

:::note info
#### facetとfilterの違い
__filter__：検索結果を絞り込むための機能
__facet__：絞り込みに使う項目をあらかじめ登録し、項目名や件数を取得できるようにする機能

→ filter単体でも絞り込みUIの構築は可能だが、facetとして登録されていると、UI構築が楽になり、レスポンス速度も向上する
:::



# 感想
#### 良いところ
- 導入・運用がとても簡単
- 検索速度が速い

#### 微妙なところ
- インクリメンタルサーチの場合、料金が高くなる可能性あり
- 厳密な仕様を把握するのが大変
- 検索のコアとなる仕様は変更不可

#### 向いている使い方
- サクッと検索機能を作りたい
- 細かい仕様は気にしない

#### 検討が必要な使い方
- インクリメンタルサーチ形式にしたい　＝>　コストの問題
- 検索ロジックを正確に把握したい　＝>　ドキュメントはあるが把握が大変
- 検索ロジックを変更したい　=> Saasなのでコア機能は変えられない