LoginSignup
2
0

Laravelで全文検索エンジンのalgoliaを使ってみた

Last updated at Posted at 2023-12-23

インフォ・ラウンジ Advent Calendar 2023 の23日目です。

はじめに

普段はElasticSearchやAWSのOpenSearch Serviceを使っているのですが、社内でalgoliaの話を聞いたのでどんなもんかと思い使ってみることにしました。

とりあえず感触を掴みたいだけなので、慣れているPHP/Laravelでやってみることにします。

Laravelのセットアップ

composer global require laravel/installer
laravel new algolia

# とりあえずSQLiteを選んでおきます
┌ Which database will your application use? ───────────────────┐
│ SQLite                                                       │
└──────────────────────────────────────────────────────────────┘

cd algolia/

php artisan -V
Laravel Framework 10.38.2

algolia用にScoutパッケージのインストール

composer require laravel/scout
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
composer require algolia/algoliasearch-client-php

ドライバ別に設定が必要なようですが、初期状態でalgoliaが使えるようになっていました。

config/scout.php
'driver' => env('SCOUT_DRIVER', 'algolia'),

ダミーデータの作成

fakerを使います。日本語を試してみたいので設定を書き換えておきます

config/app.php
'faker_locale' => 'ja_JP',

Seederでデータ投入します。とりあえずユーザを100人くらい

database/seeders/DatabaseSeeder.php
public function run()
{
    \App\Models\User::factory(100)->create();
}
# DB作成&投入
php artisan migrate
┌ Would you like to create it? ────────────────────────────────┐
│ Yes                                                          │
└──────────────────────────────────────────────────────────────┘

php artisan db:seed

100人のユーザが作成されました

php artisan tinker
Psy Shell v0.11.22 (PHP 8.2.10  cli) by Justin Hileman
> User::all()
[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
= Illuminate\Database\Eloquent\Collection {#7355
    all: [
      App\Models\User {#7357
        id: 1,
        name: "吉本 さゆり",
        email: "haruka.sakamoto@example.net",
        email_verified_at: "2023-12-23 02:40:35",
        #password: "$2y$12$H4vyHtxOyoCX7zM0qDNdheJdnpwzhQMQ3jGMNTRph0LsLq0/TaGpa",
        #remember_token: "D3q80KvS7u",
        created_at: "2023-12-23 02:40:36",
        updated_at: "2023-12-23 02:40:36",
      },
      App\Models\User {#7358
        id: 2,
        name: "工藤 舞",
        email: "tanaka.hideki@example.com",
        email_verified_at: "2023-12-23 02:40:36",
        #password: "$2y$12$H4vyHtxOyoCX7zM0qDNdheJdnpwzhQMQ3jGMNTRph0LsLq0/TaGpa",
        #remember_token: "uiXlXq4SDV",
        created_at: "2023-12-23 02:40:36",
        updated_at: "2023-12-23 02:40:36",
      }
・・・(

algoliaに投入

アカウント作成等は割愛しますが、ApplicationKeyとAdminKeyを取得してenvに書いておきます。

.env
ALGOLIA_APP_ID=XXXXXX
ALGOLIA_SECRET=XXXXXXXXXXXXXXXXXXXXXXX

atrisanにコマンドが追加されるのでimportします。この程度なら一瞬で終わります。

php artisan scout:import "App\Models\User"
Imported [App\Models\User] models up to ID: 100
All [App\Models\User] records have been imported.

algoliaのindexを確認してみましょう。

スクリーンショット 2023-12-23 12.45.47.png

ここでindexの言語設定を変えておきます。Laravel側から変える方法はちょっとわかりませんでした(無いかも)。Index LanguagesとQuery LanguagesにJapaneseを追加します。

スクリーンショット 2023-12-23 12.02.01.png

algoria上で検索してみます。

スクリーンショット 2023-12-23 12.04.15.png

読みで検索できているので、うまくいっているように見えますね。

Laravel側からalgoriaを使う

Viewを作るのは面倒なので、コマンドで検索機能だけ確認してみましょう。

php artisan tinker
Psy Shell v0.11.22 (PHP 8.2.10  cli) by Justin Hileman

> User::search('たろう')->get()

[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
= Illuminate\Database\Eloquent\Collection {#6361
    all: [
      App\Models\User {#7337
        id: 87,
        name: "山口 太郎",
        email: "naoto11@example.org",
        email_verified_at: "2023-12-23 02:40:36",
        #password: "$2y$12$H4vyHtxOyoCX7zM0qDNdheJdnpwzhQMQ3jGMNTRph0LsLq0/TaGpa",
        #remember_token: "4RxlBWJQg4",
        created_at: "2023-12-23 02:40:36",
        updated_at: "2023-12-23 02:40:36",
      },
      App\Models\User {#7335
        id: 10,
        name: "田中 太郎",
        email: "kharada@example.com",
        email_verified_at: "2023-12-23 02:40:36",
        #password: "$2y$12$H4vyHtxOyoCX7zM0qDNdheJdnpwzhQMQ3jGMNTRph0LsLq0/TaGpa",
        #remember_token: "2LO8hxOoWg",
        created_at: "2023-12-23 02:40:36",
        updated_at: "2023-12-23 02:40:36",
      },
    ],
  }

できているようですね。

ユーザを追加してみましょう

> $user = new App\Models\User;
= App\Models\User {#7287}

> $user->name = "ジョナサン・ジョースター"
= "ジョナサン・ジョースター"

> $user->email = "jojo@example.com";
= "jojo@example.com"

> $user->password = 'hogefuga'
= "hogefuga"

> $user->save();
= true

> User::search('じょなさん')->get()
= Illuminate\Database\Eloquent\Collection {#7359
    all: [
      App\Models\User {#7860
        id: 101,
        name: "ジョナサン・ジョースター",
        email: "jojo@example.com",
        email_verified_at: null,
        #password: "$2y$12$j/srUBj0AfeL11aZve2aWOeulXYgCIPkBze6bTDHpdbQ8AFFaHpbG",
        #remember_token: null,
        created_at: "2023-12-23 03:08:19",
        updated_at: "2023-12-23 03:08:19",
      },
    ],
  }

簡単ですね。save()するだけでalgoriaにも反映されます。

Scout Extended

ちなみにalgoliaではLaravel用の拡張パッケージが用意されているようなので、インストールしておくと便利そうです。

composer require "algolia/scout-extended"

機能が色々あるようなのですが、例えば

インデックスのステータスチェック

php artisan scout:status
 🔎 Analysing information from: [App\Models\User]

 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ----------------- ------- ----------------- --------------- ----------------
  Searchable        Index   Settings          Local records   Remote records
 ----------------- ------- ----------------- --------------- ----------------
  App\Models\User   users   Local not found   101             101
 ----------------- ------- ----------------- --------------- ----------------

ダウンタイムなしでのインデックス再生成(一時インデックスを作って差し替え)

php artisan scout:reimport
 🔎 Importing: [App\Models\User]

 0/3 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░]   0% Creating temporary index temp_users
 2/3 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░]  66% Importing records to index temp_users
 3/3 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100% Replacing index users by index temp_users

みたいなことができます。ElasticSearchではaliasを使ったりするとなかなか面倒なこともありますが、このような拡張が用意されているのは嬉しいです。

他にも複数モデルにまたがる検索などもできるようなので、ドキュメントを参照してみてください。

まとめ

全文検索エンジンのalgoliaをLaravelから使ってみました。scoutや拡張機能が用意されているので、普段のLaravel開発から入りやすいなと思いました。細かい設定もかなりあるので、柔軟な対応もできそうです。

参考URL

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0