AlgoliaのRulesを使って検索結果をカスタマイズする

# AlgoliaのRulesとは？
検索結果を必要に応じてfine-tuneしていくための機能です。
ユーザーによるQueryや、ユーザーのContextや、その他の条件(Conditionless。デフォルトの検索パラメータ等をコーディング作業をしないで設定)を設定可能です。もちろん、一定期間だけ指定して設定することも出来ます。

# AlgoliaのRulesのStructure

ざっくり以下のような形の設定になります。

- [IF]もしxxx: Queryのパターン、Context, またはConditionlessを使って条件を設定
- [THEN]だったらxxx: 結果を設定
- 一時的な場合: その期間を設定

## Condition
条件には以下のようなものが挙げられます

- ユーザーのクエリに、例えば"安い"というキーワードが入っている場合
- ユーザーのコンテキスト(ruleContext)に、例えば"mobile"という文字列が入っている場合
- 例えばユーザーのいる場所から半径1km以内(コーディング無しで2kmに条件の変更が可能)

## Consequence
結果としてどうするかは以下のような定義ができます

- Promote a Result: 特定のアイテムやカテゴリをブーストする
- Hide a Result: 特定のアイテムを表示させない
- Add a Query Parameter: クエリのパラメータを追加する("近く"というクエリキーワードがあったらaroundRadiusを追加したり)
- Remove Word: 特定のキーワードをクエリから削除
- Replace Word: クエリにある特定のキーワードを置き換える
- Replace Query: 別のクエリに置き換える
- Return Custom Data: カスタムJSON文字列を検索結果として返す
- Filter Matching Attributes: 結果にフィルタを適応する

## Validity period 
例えば季節のセールの場合は、セール期間中だけルールを適用する

# 具体的な設定

## Query
クエリの設定には以下の条件を設定できる

- is: 一致
- contains: 含まれる
- starts with: 〜ではじまる
- ends with: 〜で終わる

## Context
- ruleContetsパラメータで指定されたもの
- 例えば"mobile"が指定されていた場合は検索結果の上位にチャージャーやケースを表示するRuleを適用すると良いかもしれない(Analyticsで分析した上で判断)

## Conditionless
- 一時的にデフォルトで適用する条件に使ったりすると便利

# Contextを使ったプラットフォーム毎の検索結果のカスタマイズ例

## クライアント側でプラットフォームを判別

```
const getPlatform = () => {
  const isMobile = ...
  // ご自身でロジックを実装してモバイルかデスクトップかを判別
  return isMobile ? 'mobile' : 'desktop';
};
```

## ruleContextsでパラメータを設定(InstantSearch.jsの場合)

```
const platformTag = getPlatform();

instantsearch.widgets.configure({
  ruleContexts: [platformTag],
});
```

## Algoliaのインデックスの設定

## contextというインデックスを作って以下のJSONデータを投入
release_dateをUnix timestampにしているのはその方が扱いやすいからです。

```
{
  "title": "Fargo",
  "year": 1996,
  "director": "Joel Coen",
  "release_date": 841795200,
  "rating": 93
}
```

841795200はコンバートしたら1996年9月4日で👇のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51469/299b3b93-36c6-bdef-3c88-6cedf7d36846.png)


## Ruleの設定はAPIでも可能

ですが、今回はなんとなくダッシュボードで。笑
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51469/9ee83f43-9e9c-a449-6d66-0669eafb5177.png)


Javascriptだと👇こんな感じ。

```
const rule = {
  objectID: 'a-rule-id',
  condition: {
    context: 'mobile'
  },
  consequence: {
    params: {
      filters: 'release_date >= 1568498400'
    }
  }
};

movies.saveRule(rule).then(() => {
  // done
});
```

日付の絞り込みとしては👇より新しいもの。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51469/327f45d9-2f25-b313-e97a-96be9e21517c.png)


# Rule Contextを設定して検索してみましょう

## デフォルトだとEmptyクエリで1件ヒット(Rule Contextを設定しない)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51469/b312dbfd-ad9a-f010-3ae5-82429049108c.png)

## Rule Contextを設定

＋ Add Query Paramter
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51469/4d5b88f6-6e9d-3ecd-62f5-5d57b2b85943.png)

SearchタブのRule Contextに入力(実際はブラウザ上のJavaScriptでクエリ実行時に👆のInstantSearchの例のようにセットする)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51469/65954e23-9ac6-59e4-3f4b-7faa0e9a1cee.png)

ruleContexts: mobileが適用されて結果は出なくなる(モバイルの場合は2019年9月14日以降で設定している為)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51469/406dc74c-fb0b-3bd6-89e9-0eecdfb7bc8a.png)

# まとめ

- AlgoliaのRulesが使いこなせるとIf-Thenの要領で幅広く色んなことが出来るようになります
- クライアントからはRule Contextのパラメータを渡すだけでよく、一旦その実装が出来れば、条件は後からAlgoliaのダッシュボード上で変更できるので開発者でなくてもやりくりが可能です
- 疑問点や気になることなどございましたら #AlgoliaJP ハッシュタグでTweetしていただければ私の方で1日1回くらいチェックしております :)