🦓

[Rails]meilisearch

2023/08/22に公開

はじめに

meilisearchを導入して検索機能を作っていきたいと思います。

https://www.meilisearch.com/
https://github.com/meilisearch/meilisearch-rails

環境

Rails 7.0.4.3
ruby 3.2.1

meilesearchをインストールする

MeiliSearchをダウンロードして実行する方法にはいくつかの方法がありますが、ここでは公式のDockerイメージを使用します。

masterKey指定しない場合コマンド実行後に作ってくれるので指定してもう一度Dockerを起動します。

docker run -it --rm -p 7700:7700 getmeili/meilisearch:latest meilisearch --master-key=masterKey

888b     d888          d8b 888 d8b                                            888
8888b   d8888          Y8P 888 Y8P                                            888
88888b.d88888              888                                                888
888Y88888P888  .d88b.  888 888 888 .d8888b   .d88b.   8888b.  888d888 .d8888b 88888b.
888 Y888P 888 d8P  Y8b 888 888 888 88K      d8P  Y8b     "88b 888P"  d88P"    888 "88b
888  Y8P  888 88888888 888 888 888 "Y8888b. 88888888 .d888888 888    888      888  888
888   "   888 Y8b.     888 888 888      X88 Y8b.     888  888 888    Y88b.    888  888
888       888  "Y8888  888 888 888  88888P'  "Y8888  "Y888888 888     "Y8888P 888  888

Config file path:	"none"
Database path:		"./data.ms"
Server listening on:	"http://0.0.0.0:7700"
Environment:		"development"
Commit SHA:		"ef3d098b4ddd4e41b3e8aa36856edb284a8a2a39"
Commit date:		"2023-08-10T10:55:50+00:00"
Package version:	"1.3.1"

Thank you for using Meilisearch!


We collect anonymized analytics to improve our product and your experience. To learn more, including how to turn off analytics, visit our dedicated documentation page: https://www.meilisearch.com/docs/learn/what_is_meilisearch/telemetry

Anonymous telemetry:	"Enabled"
Instance UID:		"************"

A master key has been set. Requests to Meilisearch won't be authorized unless you provide an authentication key.

Check out Meilisearch Cloud!	https://www.meilisearch.com/cloud?utm_campaign=oss&utm_source=engine&utm_medium=cli
Documentation:			https://www.meilisearch.com/docs
Source code:			https://github.com/meilisearch/meilisearch
Discord:			https://discord.meilisearch.com

[2023-08-22T04:49:16Z INFO  actix_server::builder] starting 8 workers
[2023-08-22T04:49:16Z INFO  actix_server::server] Actix runtime found; starting in Actix runtime

ポート7700でmeilesearchのダッシュボードにアクセス出来ましたらOKです。

meilisearch-railsをインストールする

gemmeilisearch-railsをインストールします。

gem 'meilisearch-rails'
bundle install

公式のドキュメントを参考にしながら進めていきます。

apiKeyを作成する

client = MeiliSearch::Client.new('http://localhost:7700', 'masterKey')

client.keysで確認できれば大丈夫です。
検索用APIキーとAdmin用APIキー二つがあるはずです。
https://www.meilisearch.com/docs/reference/api/keys#create-a-key

初期設定

config/initializers内にmeilisearch.rbを作成します。

config/initilizers/meilisearch.rb
MeiliSearch::Rails.configuration = {
  meilisearch_url: 'http://localhost:7700'
  meilisearch_api_key: ENV["MEILISEARCH_API_KEY"],
  timeout: 2,
  max_retries: 1,
}
  1. timeout: 2:
    このオプションは、APIリクエストがタイムアウトするまでの最大待ち時間を指定します。
    2秒間(ここでは 2 になっています)レスポンスが受信されない場合、タイムアウトエラーが発生します。
    タイムアウトの設定は、サーバーが応答しない場合やネットワーク遅延が発生した場合に、クライアントが長時間リクエストを待たされるのを防ぐために使用されます。

  2. max_retries: 1:
    このオプションは、APIリクエストの再試行回数を指定します。
    リクエストが失敗した場合に、最大で1回までリトライを試みるという意味です。
    リトライは、ネットワークエラーや一時的なサーバーエラーなどが発生した場合に、リクエストの成功を試みるために使用されます。
    1回のリトライが行われた後にも成功しない場合、エラーハンドリングが行われることが多いです。

Modelファイルを設定する

検索させたいモデルファイル内にMeiliSearchをインクルードし、カラム名を指定します。
指定しない場合全てのカラムが検索対象になります。

app/models/log.rb
class Log < ActiveRecord::Base
  include MeiliSearch::Rails

  meilisearch do
    attribute :title, :body
    
    displayed_attributes [:user_id, :created_at]
  end
end

モデルをインデックスする

irb(main):003:0> Log.reindex!   
  Log Load (0.4ms)  SELECT "logs".* FROM "logs" ORDER BY "logs"."id" ASC LIMIT ?  [["LIMIT", 1000]]
=> nil        

インデックスされたレコードがダッシュボードで表示されることを確認します。

関連付けしたモデルも一緒に検索する

app/models/log.rb
class Log < ApplicationRecord
  include MeiliSearch::Rails

  has_many :contributions, dependent: :destroy

  meilisearch do
+    attribute :contributions do
+      contributions.pluck(:content)
+    end

  end
end

インデックスを実行し変化を反映させます。

irb(main):018:0> Log.reindex!              
  Log Load (0.1ms)  SELECT "logs".* FROM "logs" ORDER BY "logs"."id" ASC LIMIT ?  [["LIMIT", 1000]]
=> nil

検索パラメーターを指定する

searchはmeilisearchが用意した検索メソッドです。

app/controllers/logs_controller.rb
class LogsController < ApplicationController
    def index
        @logs = Log.search(params[:query])
    end
end

検索フォームを作成する

app/views/logs/index.html.erb
<%= form_with url: logs_path, method: :get do |form| %>
  <%= form.search_field :query %>
  <%= form.button '検索する'  %>
<% end %>

ページネーション

検索結果のページネーションを指定することもできるのでgemに合わせて使ってください。

config/initilizers/meilisearch.rb
MeiliSearch::Rails.configuration = {
   pagination_backend: :kaminari # :will_paginate
}

https://github.com/meilisearch/meilisearch-rails#backend-pagination-with-kaminari-or-will_paginate-

終わりに

Ransack以外の検索gemも試したかったのでmeilisearchを使ってみました。
間違えたところがあれば教えていただけますと幸いです。

Discussion