インフォ・ラウンジ 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が使えるようになっていました。
'driver' => env('SCOUT_DRIVER', 'algolia'),
ダミーデータの作成
fakerを使います。日本語を試してみたいので設定を書き換えておきます
'faker_locale' => 'ja_JP',
Seederでデータ投入します。とりあえずユーザを100人くらい
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に書いておきます。
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を確認してみましょう。
ここでindexの言語設定を変えておきます。Laravel側から変える方法はちょっとわかりませんでした(無いかも)。Index LanguagesとQuery LanguagesにJapaneseを追加します。
algoria上で検索してみます。
読みで検索できているので、うまくいっているように見えますね。
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