ブログ移行日記(その4) - 検索機能(Algolia)の導入

Posted by johtani on Tuesday, January 28, 2020
Last Modified on Wednesday, January 29, 2020

目次

ブログ移行日記(その4)です。その他の記事はこちら。

前回までで、なんとなく移行は終わってます。 今回はテーマで使えるようになっているブログの検索機能の導入の話です。

検索サービスはAlgoliaを利用します。 OctopressのころはElastic社のサービスであるElastic Site Searchの機能を利用して、クローリングしてから検索できるようにしていましたが、Hugoで導入できるモジュール?があったので、今回からこちらに移行しました。

参考記事

Algoliaとは?

検索のas-a-serviceをやっている会社です。Wikipediaによると本社はサンフランシスコにあるみたいですね(フランスの会社のイメージでした。起業された方がフランス出身だからかなぁ?)。 クラウドで検索インデックスを保持でき、API経由で検索したり登録したりできる感じのサービスです。内部で使われているのはOSSではない独自の検索エンジンです。

クラウドで提供されているサービスなのでサクッと検索を使い始めることができるのがいい点ですね。 また、小さな非商用のプロジェクトにフリーで利用できるプランも提供されているようです(2020年1月現在)。

Algoliaのサービス登録からインデックス作成

私が利用しているテーマで設定する方法の記載があったので手順の通りにやってみました。 大きく2つの作業(Algolia側とHugo側)が必要です。まずは、Algoliaで必要な作業から。作業の流れだけ記載しておきます。詳細は「Static site search with Hugo + Algolia」の3)を確認してください。

  1. Algoliaのサインアップ(すでにアカウントがあれば不要)
  2. New Applicationの作成(名前とプランの指定)
  3. リージョンの指定
  4. インデックス名の指定
  5. APIキーを確認

です。これで、Algolia側の準備は完了です。

今回は関係ないですが、Algoliaの管理画面で、利用状況(データ登録などの操作回数、クエリの回数、インデックスに保存されているレコード数)の確認が可能です。 ほかにも有料プランを利用するとAnalyticsなどもできるようです。

Hugo側で必要な設定

今度はHugo側です。Hugoのサイトのディレクトリに移動してからの作業です。

仕組みとしては、

  1. Hugoのoutput機能でAlgolia向けのJSONファイルを生成する
  2. Node.jsのライブラリを使用してAlgoliaに1.で生成したJSONを登録、更新する
  3. 検索画面の作成

という流れになります。 ですので、作業としては以下のとおりです。

  1. Output出力の設定(すでにテーマ側で設定されているので、特に作業は必要なし)
  2. npm環境の構築(Hugoのconfig.tomlと同じディレクトリ階層)
    1. Node.jsのインストール(必要であれば)
    2. npm環境の初期化
    3. npmでatomic-algoliaのインストール
    4. atomic-algolia向けの設定(登録のためのAPI関連の設定)
    5. Algolia向けJSONの出力設定
  3. 検索関連の設定
    1. content/search/placeholder.mdの作成
    2. 検索用のAPIキーなどを設定

npm関連の作業

以下、npm関連の作業です。

  1. Node.jsのインストール(必要であれば)
    • 割愛します。環境に合わせてインストールしてください。私はnvm経由でインストールしています。
  2. npm環境の初期化
    • Hugoのディレクトリでnvm initを実行
  3. npmでatomic-algoliaのインストール
    • Hugoのディレクトリでnpm install atomic-algolia --save
  4. atomic-algolia向けの設定(登録のためのAPI関連の設定)
    • Hugoのディレクトリに.envファイルを作成し、以下を設定します。
  5. Algolia向けJSONの出力設定
    • 特に変更なし(config.tomlに少し設定があります)。
ALGOLIA_APP_ID=AlgoliaのApplication ID
ALGOLIA_ADMIN_KEY=AlgoliaのAdmin API Key
ALGOLIA_INDEX_NAME=先程作ったインデックス名
ALGOLIA_INDEX_FILE=public/algolia.json

最後のALGOLIA_INDEX_FILEは固定文字列でいいと思います。 hugoコマンドを実行するとpublicディレクトリ配下にalgolia.jsonというファイルが生成され、Algolia登録用のJSONが出力されています。

余談 : algolia.jsonの出力の設定は、config.tomlに記載があります。また、JSONファイルのテンプレート自体はthemes/hugo-theme-cleanwhite/layouts/_default/list.algolia.jsonにあります。Algoliaに登録するデータの構造など変更をする場合はこのテンプレートをカスタマイズすれば良さそうです。

検索関連の設定

実際に検索の画面を表示するために、検索用の画面と、検索用のAPIの設定が必要です。

  1. content/search/placeholder.mdの作成
    • /search/が検索用のページになります。空のファイルです。実際にはJavaScriptが検索用の窓を表示したりしてくれます(これが必要な理由がまだ不明だなぁ)。
  2. 検索用のAPIキーなどを設定

以下の値を設定します。

  algolia_search = true
  algolia_appId = "AlgoliaのApplication ID"
  algolia_indexName = "作成したインデックス名"
  algolia_apiKey = "AlgoliaのSearch-Only API Key"

以上でAlgolia関連の設定などの作業が終了です。

Algoliaへのデータ登録方法

最後に、実際にデータを登録する必要があります。 手順は、以下のとおりです。

  1. hugoコマンドの実行(htmlと一緒に登録データのalgolia.jsonを生成)
  2. npm run algoliaコマンドの実行(atomic-algoliaを利用してAlgoliaにデータを登録)

設定などが問題なければ、Algoliaの管理画面で登録ができているはずです。 実際にブログのデプロイにはdeploy.shというファイルをこちらを元に作成して使っています。このなかで、hugoコマンド実行後にnpm run algoliaを実行するようにしいます。

今後の課題

Hugoで生成された記事はそれぞれのブログポスト以外に、タグごとのページも生成されています。 こちらも実はAlgoliaのインデックスに登録されていて、タグを入力すると、タグ名のリンクが出てきます。

こちらはelasticsearchで検索したときの検索結果です。1件目はタグページです。

これらのページはAlgoliaに登録しないようにするのが良さそうかな?と考えているところです(考えてるだけ)。

2020/01/29更新

list.algolia.jsonを編集して、記事だけをインデックスするように修正しました。 テーマに存在するlayouts/_default/list.algolia.jsonを、自分のところにコピーし、次のように変更しました。if文を1行追加して、postという種類のものだけを出力するようにしました。

{{/* Generates a valid Algolia search index */}}
{{- $.Scratch.Add "index" slice -}}
{{- $section := $.Site.GetPage "section" .Section }}
{{- range .Site.AllPages -}}
  {{- if or (and (.IsDescendant $section) (and (not .Draft) (not .Params.private))) $section.IsHome -}}
    {{- if (and (eq .Section "post") (ne .URL "/post/")) -}}
      {{- $.Scratch.Add "index" (dict "objectID" .UniqueID "date" .Date.UTC.Unix "description" .Description "dir" .Dir "expirydate" .ExpiryDate.UTC.Unix "fuzzywordcount" .FuzzyWordCount "keywords" .Keywords "kind" .Kind "lang" .Lang "lastmod" .Lastmod.UTC.Unix "permalink" .Permalink "publishdate" .PublishDate "readingtime" .ReadingTime "relpermalink" .RelPermalink "html" .Params.Description "title" .Title "type" .Type "url" .URL "weight" .Weight "wordcount" .WordCount "section" .Section "tags" .Params.Tags "categories" .Params.Categories "author" .Params.authors "content" .Params.Description "excerpt_html" .Params.Description "excerpt_text" .Params.Description "summary" .Summary)}}
    {{- end -}}
  {{- end -}}
{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}

まとめ

これで、ブログ内記事検索ができるようになります。 Algoliaは個人の非商用利用の場合、フリープランが用意されているのがありがたいですね。 まだ、Hugoと連携しただけで、Algolia自体でどんな機能があって、どんなことができそうかといったところは調べていませんが、簡単に利用できるのはとても助かります。

まぁ、個人ブログの検索機能ってそんなに使う人はいないんですが、自分としては便利かなぁと。


comments powered by Disqus