🐈

【Docker】全文検索エンジン Meilisearch の開発環境を構築する

2024/01/10に公開

現在開発中のサービスで、検索機能を実装しています。
検索機能を実装するためには RDB のあいまい検索機能(SQLLIKE 句)を使う以外にも、ElasticsearchSolrAmazon CloudSearchAmazon OpenSearch ServiceAlgoliaMeilisearch などの全文検索エンジンを使う方法があります。

今回は、価格面(セルフホスティングが可能)と学習コスト(シンプルな API)、実装したい機能(インスタント検索)に対する性能などの面から Meilisearch を選択したので、とりあえず Docker で開発環境を構築します。

サンプルプロジェクト

コードなどはここから確認できます。

https://github.com/ndjndj/playground/tree/main/meili-docker

この記事でやること

  • Meilisearch について軽く紹介
  • Docker を用いた Meilisearch の開発環境の構築
  • テストデータの作成
  • API を叩いてみる

この記事でやらないこと

  • Elasticsearch, Amazon OpenSearch Service, Algolia などの他の全文検索エンジンサービスとの比較
  • Meilisearch cloud の使用方法
  • Meilisearch をホスティングする方法
    • AWS EC2 へのホスティングについて別記事で紹介する予定

Meilisearch について

MeilisearchMeilisearch 社によって開発されている Rust 製の全文検索エンジンです。

デモサイトはこちらから。

冒頭でも述べたとおり、シンプルな API と検索機能のパフォーマンスの高さ、省メモリであることなどの点に魅力を感じて Meilisearch の導入を決めました。
一方で細かいカスタマイズや日本語検索についてはまだ苦手とのことです。
詳細はこちらの記事やこちら, こちらの記事が非常にわかりやすいです。

Docker で環境構築してみる

Meilisearch の公式から docker image が提供されているのでそちらを利用します。

# compose.yml
version: '3'
services: 
  meilisearch: 
    image: getmeili/meilisearch:v1.5 # バージョンは任意
    ports:
      - "7700:7700"
    environment: # あとでつかいます(本番環境ではもっと複雑なキーを使用します)
      - MEILI_MASTER_KEY=meili-master-key
    volumes: # データ部分をマウントする
      - ./meili_data:/meili_data

起動

docker compose up

プレビュー画面に入ってみる

作成したインデックスから検索機能をカジュアルにテストすることができる画面です。
API キーの入力を求められるので、compose.yml で設定したキーを入力

次はテストデータを作成して、検索機能を試してみます。

インデックス作成

テストデータの json ファイルを作成し、Meilisearch の API 経由でドキュメント・インデックスを作成していきます。
ドキュメントとは、RDB でいうとレコードで、インデックスとはテーブルみたいなものです。
Meilisearch では、ひとつひとつのデータをドキュメントとよび、ドキュメントのコレクションをインデックスとよんでいます。

テストデータの json ファイルを作成

今回は user インデックスを作成していきます。
サンプルデータはこちらから、レコード数は10万件作成しました。

[
    {
        "uid": "100000",
        "name": "山田 太郎",
        "name_ruby": "yamada taro",
        "age": "7",
        "pref": "茨城県",
        "pref_code": "08",
        "tel": "090-0000-0000",
        "url": "http://example.com"
    }
]

API 経由でインデックス作成

下記の curl コマンドを実行し、API を呼び出します。(', " の違いなどは適宜修正してください)

# サンプルデータ.json があるディレクトリで実行する
curl \
  -X POST 'http://localhost:7700/indexes/{インデックス名}/documents?primaryKey={任意のキー}' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer meili-master-key' \
  --data-binary @sample.json
  
# コマンドプロンプト用  
curl -X POST "http://localhost:7700/indexes/{インデックス名}/documents?primaryKey={任意のキー}" -H "Content-Type: application/json" -H "Authorization: Bearer meili-master-key" --data-binary @sample.json

下記のようなレスポンスが返ってくれば成功です。
Meilisearch のデータベース操作のほとんどが非同期であるため、ドキュメント・インデックスを作成する上記の操作は一度、キューに追加され順番に実行されていきます。
statusenqueued を示していれば、キューに追加されたことがわかります。

{
	"taskUid":0,
	"indexUid":"users",
	"status":"enqueued",
	"type":"documentAdditionOrUpdate",
	"enqueuedAt":"2024-01-10T02:27:06.751515253Z"
}

作成状況の確認

taskUid を指定して、下記の curl コマンドを実行し、API を呼び出します。(', " の違いなどは適宜修正してください)

curl \
  -X GET 'http://localhost:7700/tasks/0' \
  -H 'Authorization: Bearer meili-master-key'
  
# コマンドプロンプト用  
curl -X GET "http://localhost:7700/tasks/0" -H "Authorization: Bearer meili-master-key"

レスポンスの status フィールドが succeeded を示していれば成功です。

{
	"uid":0,
	"indexUid":"users",
	"status":"succeeded",
	"type":"documentAdditionOrUpdate",
	"canceledBy":null,
	"details":{
		"receivedDocuments":100000,
		"indexedDocuments":100000
	},
	"error":null,
	"duration":"PT24.046323975S",
	"enqueuedAt":"2024-01-10T02:27:06.751515253Z",
	"startedAt":"2024-01-10T02:27:06.79580607Z",
	"finishedAt":"2024-01-10T02:27:30.842130045Z"
}

プレビュー画面での確認

プレビュー画面を更新して、インデックスが作成されていることを確認します。

API を叩いてみる

検索

インデックスが作成されたことが確認できたら、API 経由で検索してみます。

下記の curl コマンドを実行し、API を呼び出します。(', " の違いなどは適宜修正してください)

curl \
  -X POST 'http://localhost:7700/indexes/{インデックス名}/search' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer meili-master-key' \
  --data-binary '{ "q": "{検索ワード}" }'
  
# コマンドプロンプト用  
curl -X POST "http://localhost:7700/indexes/{インデックス名}/search" -H "Content-Type: application/json" -H "Authorization: Bearer meili-master-key" --data-binary "{ \"q\": \"{検索ワード}\" }"

インデックスの削除

DELETE メソッドでインデックス名を指定すればインデックスを削除することができます。
非常にシンプルです。

curl \
  -X DELETE 'http://localhost:7700/indexes/{インデックス名}' \
  -H 'Authorization: Bearer meili-master-key'
  
# コマンドプロンプト用
curl -X DELETE "http://localhost:7700/indexes/{インデックス名}" -H "Authorization: Bearer meili-master-key"

さいごに

これで Docker を用いた Meilisearch を利用するための開発環境を整えることができました。
Meilisearch では、様々な言語で利用するための SDK も充実しており、実装もスムーズにできそうです。

https://github.com/meilisearch/integration-guides

参考

Meilisearch について

https://qiita.com/mosuka/items/fbda479b25a7ccd7c350
https://blog.meilisearch.com/meilisearch-vs-elasticsearch/
https://www.meilisearch.com/docs/learn/what_is_meilisearch/comparison_to_alternatives

Docker での環境構築

https://www.meilisearch.com/docs/learn/cookbooks/docker
https://zenn.dev/shiguredo/articles/docker-compose-timescaledb-meilisearch

テストデータ作成

https://www.meilisearch.com/docs/learn/getting_started/quick_start

テストデータ作成に使用したツール

https://tm-webtools.com/Tools/TestData

SDK について

https://github.com/meilisearch/integration-guides

Discussion