InstantSearch.js で Algolia をはじめよう

この記事は Algolia Advent Calendar 2020 の1日目の記事になります。


Algoliaに関して、以下のようなフィードバックをいただくことがよくあります

  • 良さそうだけど、どうやってはじめたらイイか分からない
  • 日本語のドキュメントがなくて取っ付きにくい
  • まずは無料で試すことが出来るの?

ということで、この記事では、Algoliaのアカウント登録をせずに、完全に無料で試してみる方法を日本語で紹介します。

InstantSearch.js

Algoliaは InstantSearch.js というJavaScriptのフロントエンドライブラリをオープンソースとして公開していて、これを用いて既に存在する Algolia Index を使ってみましょう、というのがこの記事の主題です。

以前、Kanazawa.rb さんで↓のハンズオンを実施させていただいたことがあるのですが、こちらとほぼ同じ内容になっていて、その際は学生の方も含めて、全ての方がコンプリートすることが出来たので、フロントエンド技術やJavaScriptにあまり詳しくない方でも安心して試してみることができると思います。

それではさっそくはじめましょう

今回作るのは以下の3つのファイルになります

  1. app.js — JavaScriptでAlgoliaのIndexにアクセス
  2. index.html — 上記1.で取得したデータを表示
  3. style.css — 上記2.のHTML表示のデザイン

まずは自分のマシンのローカルにフォルダを作りましょう。そして、その中に空のindex.htmlとapp.jsとstyle.cssを配置します。

HTML

↓のようなHTMLを作成していきます。ポイントとしてはCDNからInstantSearch.jsに関連する3つのファイル、そして、style.css と app.js を読み込んでいるところで、これによってAlgoliaのIndexにアクセスしたり、表示のレイアウトを整えたりしてくれます。

  1. https://cdn.jsdelivr.net/npm/algoliasearch@4/dist/algoliasearch-lite.umd.js
  2. https://cdn.jsdelivr.net/npm/instantsearch.js@4
  3. https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css

bodyには検索ボックスがあって、mainの左側にブランドや価格での絞り込みを配置して、右側に検索結果を表示する感じです。また、style.css と app.js はこれから作っていくファイルです。

<!DOCTYPE html>
<html>
  <head>
    <title>InstantSearch.js で Algolia</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css"
    />
    <link rel="stylesheet" type="text/css" href="style.css" />
  </head>

  <body>
    <header>
      <div id="searchbox"></div>
    </header>

    <main>
      <div id="left-column">
        <h5 class="filter-title">Brands</h5>
        <div class="filter-widgets" id="brands"></div>
        <h5 class="filter-title">Price</h5>
        <div class="filter-widgets" id="price"></div>
      </div>
      <div id="right-column">
        <div id="hits"></div>
        <div id="pagination"></div>
      </div>
    </main>
    <script src="https://cdn.jsdelivr.net/npm/algoliasearch@4/dist/algoliasearch-lite.umd.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4"></script>
    <script src="app.js"></script>
  </body>
</html>

CSS

HTMLのmainの部分を右70%、左30%にするよ、というレイアウトと、上記でclass指定しているfilter系の設定と、後からJavaScriptの中でclass指定されるヒットした検索結果データを表示する際のデザイン指定になります。まぁ、なんというか、デザインは今回の主題からは少し外れるところもあるのでミニマムな感じで。

main {
  display: flex;
  margin-top: 10px;
}

#left-column {
  flex-basis: 30%;
}

#right-column {
  flex-basis: 70%;
  display: flex;
  flex-direction: column;
}

h5.filter-title {
  font-size: 1.05em;
  font-weight: bold;
  border: none;
  margin-top: 0;
  margin-bottom: 5px;
  text-transform: uppercase;
  color: #3a4570;
}

.filter-widgets {
  border-bottom: #eee solid 3px;
  margin-right: 30px;
  margin-bottom: 20px;
}

.hit-title {
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-between;
}

.hit-title > .price {
  display: flex;
  margin-top: 5px;
  height: 16px;
  font-weight: normal;
  border: 1px solid grey;
  padding: 2px 6px;
  border-radius: 250px;
  font-size: 0.9em;
  align-items: center;
}

main h4 {
  font-size: 1em;
  color: #222;
  margin-top: 4px;
  margin-bottom: 4px;
  line-height: 1.5;
}

JavaScript

いよいよ本題に入って参りました。やることごとにソースの中身を紹介していきます。上から順番にapp.jsにコピペして行けば動くと思います。

まずはAlgoliaのIndexにアクセスするためのオブジェクトを生成するところから。Algoliaのアカウントを作るとAPP IDと検索専用のAPI Keyが払い出されますが、今回は InstantSearch.js の Getting Startedページに書かれているものを使います。

const searchClient = algoliasearch(
  "B1G2GM9NG0", // APP ID
  "aadef574be1f9252bb48d4ea09b5cfe5" // Search Only API Key
);

const search = instantsearch({
  indexName: "demo_ecommerce",
  searchClient
});

次に、上記で作った検索クライアントオブジェクトを使って、検索BOXを配置します。containerは上記のindex.htmlで定義したdiv id=”searchbox”に検索ボックスを表示する指定で、placeholderは検索ボックスにデフォルトで表示されている文言です。このようにAlgoliaで既に用意されているウィジェットを使って宣言的にフロントエンドのUIを構築していけるのがInstantSearch.jsの特徴です。

search.addWidget(
  instantsearch.widgets.searchBox({
    container: "#searchbox",
    placeholder: "検索してみましょう"
  })
);

そして、検索ボックスのWidgetの下に search.start(); という1文を入れてみましょう。これによってWidgetが動作するようになります。

search.start();

ということで、ここで、一度index.htmlをブラウザで表示してみましょう。↓こんな感じに見えればOKです。今Widgetで設置した検索ボックスと、index.htmlのmainの左側で後で絞り込み用に使うBrandsとPriceが表示されています。

次がこの記事で一番難しいといいますか、長い部分になりますが、hitsというウィジェットを使って、Algoliaから取得した検索結果データをHTMLのタグを使う形でindex.htmlのmainの右側の div id=”hits” をcontainerで指定して表示させます。こちらは上記の searchBox Widgetの定義 と、search.start(); の間に記載していきます。

templateが実際にデータを整形して表示するところになりますが、検索結果データから画像のパスを取得してimgタグのsrc属性に設定して、name(商品名)、price(価格)、description(商品説明)はそれぞれ見やすいようにCSSのクラスを指定したり、検索した部分と一致するところをハイライトさせたりする定義が入っています。また、name, price, descriptionといった属性はそれぞれAlgoliaのIndexにデータを投入する時に設定するものになります(今回は既に存在するAlgoliaのIndexを使っているためデータ投入に関しては省略)。

search.addWidget(
  instantsearch.widgets.hits({
    container: "#hits",
    templates: {
      item: data => `
      <img src="${data.image}"/>
        <div>
          <div class="hit-title">
            <h4>${instantsearch.highlight({
              attribute: "name",
              hit: data
            })}</h4>
            <div class="price">$${data.price}</div>
          </div>
        <p>${instantsearch.highlight({
          attribute: "description",
          hit: data
        })}</p>
      </div>
      `,
      empty: "<h1>ヒット無し</h1>"
    }
  })
);

ここでindex.htmlを開くと↓のように iphone などのキーワードで検索が出来るようになっていると思います。(デフォルトは20件のデータが表示されているかと思います。)

ブランドと値段のWidgetを追加

イイ感じに全文検索が出来るようになってきたところで、続いて、InstantSearch.jsのWidgetを使って、リファインメント(フィルタリング)をしていきたいと思います。

HTML的にはmainの左側(left-column)のbrandsとpriceの部分になります。

      <div id="left-column">
        <h5 class="filter-title">Brands</h5>
        <div class="filter-widgets" id="brands"></div>
        <h5 class="filter-title">Price</h5>
        <div class="filter-widgets" id="price"></div>
      </div>

ブランドは多岐に渡るので、このリファインメントリストそのものをsearchableにする形でWidgetをapp.jsに追加します。どうでしょうか。非常に直感的ではないでしょうか。

search.addWidget(
  instantsearch.widgets.refinementList({
    container: "#brands",
    attribute: "brand",
    searchable: true,
    searchablePlaceholder: "ブランドで検索"
  })
);

続いて値段。レンジで数字を入力できるWidgetになります。

search.addWidget(
  instantsearch.widgets.rangeInput({
    container: "#price",
    attribute: "price"
  })
);

HTMLを開くと↓のように、簡単に絞り込みを行う機能の追加が出来たことが分かると思います。

Widgetは他にもたくさんあります

Algoliaのサポートエンジニアの半田さんが↓のようにTweetしてくれていますが、InstantSearchにはウィジェットのショーケースがあるので、これを活用して部品を追加していくことが出来ます。

いかがだったでしょうか?

AlgoliaのInstantSearch.jsを活用すれば簡単にState of ArtなSearch and Discoveryな体験を構築していくことが可能であることがご理解いただけたのではないかと思いますが、もし、ご質問や気になる点などございましたら、 #AlgoliaJP ハッシュタグでTwitterに投稿していただければ幸いでございます。

コメント

タイトルとURLをコピーしました