Algoliaでリアルタイム検索を実装する 第1回 AlgoliaのAPIクライアントを使う
Algoliaはリアルタイム検索機能をAPI経由で提供するサービスです。第1回目はAPIクライアントを使う方法で、もっともシンプルな実装をします。まずはAlgoliaを試してみましょう。
はじめに
本シリーズでは、リアルタイム検索機能を提供するサービスであるAlgolia*を紹介します。
*注:Algoliaは再登場
Algoliaは一から学ぶJAMstack 第5回 高機能サイトを実現するAPIとサービスにて、JAMstackと組み合わせて使いやすいサービスとして、簡単にですが登場しました。
検索機能を自前で用意しようとすると、サーバーやインフラ、またそれらを実装するための人員などで、多くのコストがかかります。コストをかけた結果、期待するだけのパフォーマンスを得られなかった、という場合もあるでしょう。
Algoliaを使うことで、サイト内検索や商品データベースの検索機能などを簡単に提供することができます。
Algoliaとは?
Algoliaは、検索機能を提供するSaaS(Software as a service)の一つです。検索機能に特化していることから、Search as a serviceとも言われます。
サイト内の全文検索や、商品データベースの検索などを得意とし、「ユーザーが何を求めて検索しているか?」という部分にフォーカスした機能を提供しています。
2019年に行われたサイト検索サービスのランキングでは、2位を獲得しており、現在注目を集めているサービスです。
また、2019年5月に日本法人を設立し、この先日本国内において、注目度が高まっていくことが期待できます。導入企業にはCookpadなどが挙げられていて、CodeGridの検索機能でも、Algoliaを使っています。
似たようなサービスには、Elastic社が提供するElastic Cloudや、Amazon Web Serviceが提供する、Amazon CloudSearch、Amazon Elasticsearch Serviceなどが挙げられます。
次に、Algoliaの特徴を見ていきましょう。
Algoliaの特徴
Algoliaの特徴は、なんと言ってもその速さです。サーバーやインフラは徹底的にチューニングされており、さらにCDNに載せることで、世界中のどこであっても100ms以内に届けることができると謳っています。実際に使ってみると、その速さを実感することができるでしょう。
もう一つの特徴として、検索入力の柔軟性と、その正確性が挙げられます。
検索結果がいくら正確でも、検索入力が非常に厳格で、一字一句間違えないように入力しないと、正しい検索結果が得られないというのであれば、実用性が高いとはいえません。
Algoliaはデフォルトの状態でも、打ち間違いの補正をしてくれるので、2、3文字打ち間違えた程度で結果がヒットしない、ということはありません。
さらに、この補正機能をカスタマイズできたり、類似する単語を一つの結果に誘導するよう設定できたり、ユーザーの行動ログから、ひとりひとり違う結果を返すことができたり……と、ユーザーが求めている結果を、より的確に届ける仕組みが提供されています。
ほかにも、どんな単語で検索が行われていて、そのうち何%が結果を返すことができなかったかなどの分析や、ABテストを行うための機能も提供されています。
これらの分析機能を使ってチューニングを行うことで、さらに正確に結果を返すことができるようになります。
なお、この記事で紹介しているデモは、次のリポジトリにあります。参照してください。
Alogoliaでリアルタイム検索を実装するサンプル
Algoliaの準備をする
それでは、実際にAlgoliaを使ってみましょう。
まずは、Algoliaにユーザー登録をします。基本は有料のサービス*ですが、初回の登録であれば14日間のフリートライアル期間が設けられています。
*注:Algoliaの料金
基本的には有料のサービスで、STARTERプランは月額$29から。また、非商用利用に限られ、検索データの分析機能がないなど機能制限はつきますが、無料のCOMMUNITYプランもあります。詳しくは料金表を参照してください。
アカウントとIndexを作成する
以下のURLからAlgoliaへアクセスし、ユーザー登録を行います。
メールアドレスなど必要事項を入力して、Algoliaからのメールを受信し、メールアドレスの実在を確認できれば、アカウントが作成できます。
アカウントの作成が終わったら、[Go to Dashboard]ボタンで、Dashboardに移動します。
すると、Index
の作成を促されます。Index
とは、Algoliaの検索エンジンが検索しやすいように最適化したデータを、保管しておくための場所のことです。また、Index
内の1オブジェクトのことをRecord
と呼んでいます。プランごとに、登録可能なRecord
数の上限が設定されています。
[Create Index]をクリックして、Index nameを登録します。
これでIndex
を作ることができました。
Indexにデータを登録する
作ったばかりのIndex
にはデータが登録されていないので、ここにデータ(Record
)を登録していきます。
画面中央の「Upload record(s)」をクリックすると、データを登録することができます。
Index
のデータ構造は、JSONで構成されていて、手動で登録するか、APIを使って登録することができます。手動で登録する場合、UIから直接JSONを書くか、ファイルをアップロードするかを選択できます。ここでは、ファイルアップロードでデータを登録してみましょう。ポップアップの中の「Upload file」をクリックします。
アップロードできるファイル形式は、JSON・CSV・TSVの3種類です。ここではJSONファイルをアップロードします。記事中でサンプルに使ったJSONファイルは 次のような構造です。
JSONの構造(1Record分)
{
"name": "中村 享介",
"kana": "なかむら きょうすけ",
"title": "フロントエンド・エンジニア",
"description": "2009年、JavaScriptの会社として株式会社ピクセルグリッドを設立。(以下省略)"
},
ダイアログ中央のアップロードエリアに、JSONファイルをドラッグ&ドロップして、「Upload」ボタンをクリックします。
これで、JSONファイルにあるRecord
が登録された状態のIndex
が作られ、検索UIを作る準備が整いました。
*注 管理画面でできること
管理画面では、データ登録の他に、Index
ごとの各種設定や、Index
をまたいだ分析などを行うことができます。
APIクライアントを使う
AlgoliaのAPIを使用して検索を実行する方法としては、次の2通りの方法があります。
- APIクライアントを使う
- Algoliaが提供するウィジェットを使う
この回では、前者のAPIクライアントを使った方法から見ていきます。APIクライアントはブラウザからでも、nodeからでも利用することができます。今回は、ローカルに開発環境を構築し、nodeでAlgoliaのAPIクライアントを叩いて、検索結果を取得してみましょう。
開発環境を構築する
npmにはalgoliasearch
というパッケージ名で登録されているので、これをインストールします。
npm install algoliasearch
TypeScript環境の場合は、DefinitelyTypedに型定義ファイルが公開されているので、併せてインストールします。
npm install --save @types/algoliasearch
これでAPIクライアントを使う準備ができました。
検索のためのコードを書く
それではさっそく、APIクライアントを使った検索を行ってみましょう。
まずは、APIクライアントを初期化して、検索の対象となるIndex
を参照するためのオブジェクトを取得します。
そのためには、「Application ID」と「API Key」が必要になります。Algoliaの管理画面からサイドメニューの「API Keys」を開き、「Application ID」と「Search-Only API Key」をコピーします。
これを踏まえて、APIクライアントの初期化を行っていきましょう。このデモではsearch.js
というファイル名で作成してみます。
APIクライアントの初期化とオブジェクトの取得(search.js)
const algoliasearch = require('algoliasearch');
const client = algoliasearch(process.env.APP_ID, process.env.API_KEY);
const index = client.initIndex(process.env.INDEX_NAME);
まず、algoliasearch
関数を使って、APIクライアントを初期化します。
サンプルコードでは、引数に環境変数(process.env
から始まる変数)を使っていますが、手元で試すだけならそれぞれのトークン情報を直打ちしてもよいでしょう*。
第一引数(process.env.APP_ID
の部分)には、「Application ID」を、第二引数(process.env.API_KEY
の部分)には、「Search-Only API Key」を渡します。
*注:トークンの管理
サンプルコードでは、Application IDなどのトークン情報は、環境変数に格納したものを読み込む書き方をしています。ローカルで試すだけなら、直接キーを埋め込んでもかまいません。実際の開発では、サンプルのように環境変数から読み込むことをおすすめします。
次に、初期化したAPIクライアントのinitIndex
メソッドを実行して、Index
を参照するためのオブジェクトを取得します。このときの引数には、作成したIndex
の名前(先ほどの例であればcodegrid-demo
)を渡します。
最後に、index
オブジェクトを使って、検索を実行します。検索にはsearch
メソッドを使います。
searchメソッドで検索を実行して出力(search.js)
const main = async () => {
const { hits } = await index.search({ query: 'JavaScript' });
console.log(hits);
}
main();
search
メソッドの第一引数には、検索条件としてさまざまな値を渡すことができます。ここでは、任意の文字列で検索したいので、query
パラメータに文字列を渡しています。これで「JavaScript
」が含まれるデータが返され、コンソールに表示されます。
search
メソッドは、検索結果を含むレスポンスをPromiseで返します。結果を受け取るには、このPromiseを待ち受けるか、もしくは第二引数にコールバック関数を指定することでも受け取ることができます。ここでは、async/await
を利用して、search
メソッドが返すPromiseの解決を待っています。
検索結果は、レスポンス内のhits
プロパティに格納されています。hits
は、先ほど登録したRecord
の配列となっているため、ここから必要な値を個別に取り出すこともできます。
hitsから必要な値を取り出す場合
hits.forEach(({ name, kana, title, description }) => {
console.log(`名前: ${name}`);
console.log(`ふりがな: ${kana}`);
console.log(`肩書: ${title}`);
console.log(`人物紹介: ${description}`);
});
デモでは特にこれらの指定はせずにconsole.log(hits)
で、すべての値を取り出しています。
nodeで実行する
最後にsearch.js
を実行してみましょう。
処理の実行
node search.js
RecordごとにJSON形式で返ってきます。
出力結果
[
{
name: '中村 享介',
kana: 'なかむら きょうすけ',
title: 'フロントエンド・エンジニア',
description: '2009年、JavaScriptの会社として株式会社ピクセルグリッドを設立。\n' +
'多数のWebリニューアル、新規立ち上げを取り仕切った経験を持ち、情報設計、フロントエンド、クラウド活用、開発フローの効率化を得意とする。\n' +
'Webをより発展させるため、新しくブラウザに実装された機能の活用事例を数多く生み出しつつ、日々、クラウドサービスを利用した効率のよい制作・開発手法の試行錯誤を続けている。\n' +
'\n現在の興味はWeb Componentsを使ったマークアップの改善とJAMstack。\n\n' +
'著書に『[WebクリエイティブのためのDOM ' +
'Scripting](https://www.amazon.co.jp/dp/4839922268/)』(単著:毎日コミュニケーションズ、2007年)など。ここ数年は書籍の執筆をせず、フロントエンド技術情報メディア「CodeGrid」で精力的に執筆活動を行っている。',
objectID: '26482840',
_highlightResult: {
name: [Object],
kana: [Object],
title: [Object],
description: [Object]
}
},
...(以下省略)...
]
まとめ
今回は検索UIを作る方法の一つ、APIクライアントを用いる方法を解説しました。シンプルな検索ですが、この仕組みをイチから実装することを考えれば、かなり楽です。
次回はローカルのnode上ではなく、ブラウザから検索機能を使う実装などを解説します。