
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、Laravelにはこの間公開したLaravel Passportで自分の登録データを取得するで紹介したような公式パッケージがいくつか存在していて、他にはソーシャルログインを実装するSocialite
が有名なところだと思います。
そして、私がもうひとつ以前から気になっていたのが、「Laravel Scout」です。
Larave Scout
は、全文検索を実装するパッケージのことで、サンプルとしては、Laravel本家のウェブサイトで検索してみるとわかりやすいでしょう。
もし全文検索が実装されると、訪問ユーザーは目的のコンテンツを見つけやすくなるので、特に検索機能が重要なウェブサイトの場合は強力な武器になるのではないでしょうか。
ということで、今回はLaravel Scout
を使って全文検索を実装する方法を紹介します。
ぜひ皆さんのお役に立てると嬉しいです
開発環境:Laravel 5.8
目次 [非表示]
Laravel Scout の仕組み
Laravel Scout
では、algoliaというウェブサイトを利用して全文検索を実現しています。
つまり、データベースの内容を事前にalgolia
へ登録しておいて、後から検索キーワードを送信することで簡単に全文検索を実現することができるというわけですね。
ちなみにalgolia
には、非商用向けに無料のアカウントを作成できるようになっていて、その場合は以下の制限がつくことになります。(2019.06.15現在)
- オペレーション(追加や検索などで1オペレーションになる):50,000 回/月
- データ数:10,000 件
Laravelにパッケージをインストールする
まずはalgolia
から登録してもいいのですが、設定ファイルをパッケージからコピーするので、先に以下のコマンドでLaravel Scout
をインストールしておきましょう。
composer require laravel/scout
続いて、パッケージからファイルをパブリッシュ(コピー)します。
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
これでconfig/scout.php
が作成されました。
続いてクライアントのパッケージです。
composer require algolia/algoliasearch-client-php:^2.2
これでパッケージのインストールは完了です。
algoliaの設定をする
algoliaにアカウントを作成する
では、algoliaのトップページへアクセスして、画面右上にある「FREE TRIAL」ボタンをクリックします。
するとメールアドレスとパスワードの入力フォームが表示されますので、この2つと利用規約のチェックボックスにチェックをオンにして送信します。
すると、入力したメールアドレスに以下のようなメッセージが送信されてきますので、「Confirm my email」ボタンをクリック。
ボタンをクリックすると、あなたについての入力を求められます。
内容は次のとおりです。
- First name ・・・ 名
- Last name ・・・ 姓
- Company ・・・ 会社
- Phone ・・・ 電話番号(省略可)
- Wat would describe you the most? ・・・ あなたについて当てはまるものを選んでください。(ぴったりのコンテンツを提供するための質問だそうですので、だいたいでいいかもしれません
)
入力が完了したら、「Next」ボタンをクリックします。
すると、どの地域のサーバーを使うかを選べるますので、Japan
を選択(おそらく自動的に選択されると思います)して「Next」ボタンをクリック。
続いて、どんな使い方をするか聞いてきますが、後で登録することもできますので、今回は「Skip」ボタンをクリックして省略することにします。
これでアカウント登録は完了です。
algoliaのAPIキーをLaravelに登録する
algolia
に登録したらLaravel側からのアクセスに必要なAPIキーを取得しておきましょう。
まずはログインして、画面左側にあるメニューから「API Kyes」をクリックします。
すると、APIキーが表示されます。
それぞれをコピーしてconfig/scout.php
に以下のように登録してください。
'algolia' => [
'id' => env('ALGOLIA_APP_ID', '(Application IDがここ)'),
'secret' => env('ALGOLIA_SECRET', '(ADMIN API Keyがここ)'),
],
※ Search-Only API Key
は使いませんので気をつけてください。
全文検索する部分をつくる
では、本題の全文検索を実装する部分を作っていきましょう。
テストデータをつくる
まずは検索するためのデータがないと始まりませんので、以下のようなSeeder
を作成してテストデータを用意します。
<?php
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$names = [
'taro' => '太郎',
'jiro' => '次郎',
'saburo' => '三郎',
'shiro' => '四郎',
'goro' => '五郎',
'rokuro' => '六郎',
'shichiro' => '七郎',
'hachiro' => '八郎',
'kuro' => '九郎'
];
foreach ($names as $name_en => $name_jp) {
\App\User::create([
'name' => $name_jp,
'email' => $name_en .'@example.com',
'password' => bcrypt('xxxxxxxx')
]);
}
}
}
※ Seeder
の作り方は以下のページの「ログイン、パスワードリマインダー機能を構築」をご覧ください。
Seeder
を実行するとこうなりました。
ただし、このままではalgolia
の方にデータが存在していませんので以下のコマンドで一気にデータをアップロードしておきましょう。
php artisan scout:import "App\User"
※ App\User
の部分は適宜変更してください。
実行すると次のような表示になります。
では、algolia
でどうなっているかを見てみましょう。
メニューの「Indices」をクリックします。
もし、うまくアップロードできていれば次のようになっています。
ちなみに逆にalgolia
のデータ全てを削除する場合は以下のコマンドを実行してください。
php artisan scout:flush "App\User"
モデルを全文検索に対応させる
Laravel Scout
はインストールするだけで有効になるわけではなく、以下のようにSearchable
トレイトを追加する必要があります。(つまり、今回はapp/User.php
ですが、適宜お好みのモデルで設定してください)
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Scout\Searchable;
class User extends Authenticatable
{
use Notifiable, Searchable;
※ Searchableを設定すると、データが追加、更新、削除された場合は自動的にalgolia
の方のデータも同期されることになります。
テストしてみる
では、これで基本的な設定は全て完了しましたので、routes/web.php
に以下のようにルーティングを追加してテストしてみましょう。
Route::get('user_search', function(){
$users = \App\User::search('太郎')->get();
foreach ($users as $user) {
echo '<li>'. $user->name .'</li>';
}
});
これをブラウザで表示すると次のようになります。
これだけみると通常の検索と変わりませんが、例えばメールアドレスをターゲットにして「ro」というキーワードで検索しても「六郎」しか結果は返ってきません。これは、「taro」「jiro」という単語ごとに検索してくれているからです。
そして、algolia
はあいまい検索にも対応していて、「siro」で検索してみると、次のように似た検索結果を自動的に返してくれます。
※ 「shiro」と「jiro」が検索にヒットしています。このあたりがalgolia
の価値ですね。
なお、複数キーワードで検索する場合は空白でつないで使います。
\App\User::search('taro example')->get();
そして、もちろんpaginate()
も使うことができますよ!
$users = \App\User::search('太郎')->paginate();
dd($users->toArray());
お疲れ様でした!
おまけ:検索対象にする項目を指定する
例えば、検索する項目をemail
とname
だけに制限したい場合です。
この場合、先ほどデータを確認したIndices
ページの「Configuration」タブをクリックし、さらに「Add as Searchble Attribute」リンクをクリックしてください。
すると以下のように検索項目を選択できますので、好きなものを選びます。
項目を選ぶとこうなります。
最後に忘れずに「Save settings」ボタンをクリックしてください。
おわりに
ということで、今回はLaravelで全文検索をサクッと実装する方法を紹介しました。
今まで自前で全文検索を自前で実装するには、mecab
などで分かち書きするなどめんどうな設定が多くありますが、Laravel Scout
を使えばそういう作業も全てスキップさせることができます。
また、途中でもちらっと書いたあいまい検索ですがこちらの記事によると日本語の検索には特殊なシステムを使って実現しているようですので(やっぱり機械学習とかでしょうか??)、より精度が高い検索を実現することができそうですね。
ぜひ、検索が重要なecサイトなどの開発に導入を検討してみてはいかがでしょうか。
ではでは〜♪