Laravel Scout を使用して全文検索を有効にする
公開: 2023-05-08Laravel フレームワークは、Web サービスを構築する開発者にとって頼りになるリソースとなっています。
オープンソース ツールとして、Laravel は、開発者が堅牢で機能的なアプリケーションを構築できるようにする、すぐに使える無数の機能を提供します。
その製品の中には、アプリケーションの検索インデックスを管理するためのライブラリである Laravel Scout があります。 その柔軟性により、開発者は構成を微調整し、インデックスを保存するドライバーを Algolia、Meilisearch、MySQL、または Postgres から選択できます。
ここでは、このツールを詳しく調べて、ドライバーを通じて Laravel アプリケーションに全文検索サポートを追加する方法を説明します。 モックアップ列車の名前を保存するためのデモ Laravel アプリケーションをモデル化し、Laravel Scout を使用してアプリケーションに検索を追加します。
前提条件
これに従うには、次のものが必要です。
- コンピューターにインストールされている PHP コンパイラー。 このチュートリアルでは PHP バージョン 8.1 を使用します。
- コンピューターにインストールされている Docker エンジンまたは Docker Desktop
- 無料で作成できる Algolia クラウド アカウント
LaravelプロジェクトにScoutをインストールする方法
Scout を使用するには、まず検索機能を追加する Laravel アプリケーションを作成する必要があります。 Laravel-Scout Bash スクリプトには、Docker コンテナ内で Laravel アプリケーションを生成するコマンドが含まれています。 Docker を使用すると、MySQL データベースなどの追加のサポート ソフトウェアをインストールする必要がなくなります。
Laravel-scout スクリプトは Bash スクリプト言語を使用するため、Linux 環境内で実行する必要があります。 Windows を実行している場合は、Windows Subsystem for Linux (WSL) を必ず構成してください。
WSL を使用している場合は、ターミナルで次のコマンドを実行して、優先する Linux ディストリビューションを設定します。
wsl -s ubuntu
次に、プロジェクトを配置するコンピュータ上の場所に移動します。 Laravel-Scout スクリプトはここにプロジェクト ディレクトリを生成します。 以下の例では、Laravel-Scout スクリプトはデスクトップディレクトリ内にディレクトリを作成します。
cd /desktop
以下のコマンドを実行して、Laravel-Scout スクリプトを実行します。 必要な定型コードを使用して Docker 化されたアプリケーションをスキャフォールディングします。
curl -s https://laravel.build/laravel-scout-app | bash
実行後、 cd laravel-scout-app
を使用してディレクトリを変更します。 次に、プロジェクト フォルダー内でsail-up
コマンドを実行して、アプリケーションの Docker コンテナーを起動します。
注:多くの Linux ディストリビューションでは、昇格された特権を開始するには、 sudo
コマンドとともに以下のコマンドを実行する必要がある場合があります。
./vendor/bin/sail up
次のようなエラーが発生する可能性があります。
これを解決するには、 APP_PORT
変数を使用して、 sail up
コマンド内でポートを指定します。
APP_PORT=3001 ./vendor/bin/sail up
次に、以下のコマンドを実行して、PHP サーバー上の Artisan を通じてアプリケーションを実行します。
php artisan serve
Web ブラウザから、http://127.0.0.1:8000 にある実行中のアプリケーションに移動します。 アプリケーションはデフォルトのルートで Laravel のようこそページを表示します。
Laravel Scoutをアプリケーションに追加する方法
ターミナルでコマンドを入力して、Composer PHP パッケージマネージャーが Laravel Scout をプロジェクトに追加できるようにします。
composer require laravel/scout
次に、vendor:publish コマンドを使用して Scout 構成ファイルを公開します。 このコマンドは、 scout.php
構成ファイルをアプリケーションのconfigディレクトリに公開します。
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
次に、ボイラープレート.envファイルを変更して、 SCOUT_QUEUE
ブール値を含めます。
SCOUT_QUEUE
値を使用すると、Scout が操作をキューに入れることができるようになり、応答時間が短縮されます。 これがないと、Meilisearch のようなスカウト ドライバーは新しい記録をすぐに反映しません。
SCOUT_QUEUE=true
また、Docker コンテナ内で MySQL データベースを使用するために、ローカルホストを指すように.envファイル内のDB_HOST
変数を変更します。
DB_HOST=127.0.0.1
モデルをマークしてインデックスを構成する方法
Scout は、デフォルトでは検索可能なデータ モデルを有効にしません。 Laravel\Scout\Searchable
トレイトを使用して、モデルを検索可能として明示的にマークする必要があります。
まず、デモのTrain
アプリケーションのデータ モデルを作成し、それを検索可能としてマークします。
モデルの作成方法
Train
アプリケーションの場合、利用可能な各列車のプレースホルダー名を保存する必要があります。
以下の Artisan コマンドを実行して移行を生成し、 create_trains_table
という名前を付けます。
php artisan make:migration create_trains_table
移行は、指定された名前と現在のタイムスタンプを組み合わせた名前のファイルに生成されます。
Database/migrations/ディレクトリにある移行ファイルを開きます。
タイトル列を追加するには、17 行目のid()
列の後に次のコードを追加します。このコードはタイトル列を追加します。
$table->string('title');
移行を適用するには、以下のコマンドを実行します。
php artisan migrate
データベースの移行を実行した後、 app/Models/ディレクトリにTrain.phpという名前のファイルを作成します。
LaravelScoutSearchable トレイトを追加する方法
以下に示すように、 Laravel\Scout\Searchable
トレイトをモデルに追加して、 Train
モデルを検索用にマークします。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; class Train extends Model { use Searchable; public $fillable = ['title'];
また、 searchable
メソッドをオーバーライドして検索インデックスを構成する必要があります。 Scout のデフォルトの動作では、モデル テーブル名と一致するようにモデルが永続化されます。
したがって、次のコードをTrain.phpファイルの前のブロックのコードの下に追加します。
/** * Retrieve the index name for the model. * * @return string */ public function searchableAs() { return 'trains_index'; } }
Scout で Algolia を使用する方法
Laravel Scout を使用した最初の全文検索では、Algolia ドライバーを使用します。 Algolia は、大量のデータを検索するために使用されるサービスとしてのソフトウェア (SaaS) プラットフォームです。 開発者が検索インデックスを管理するための Web ダッシュボードと、好みのプログラミング言語でソフトウェア開発キット (SDK) を介してアクセスできる堅牢な API を提供します。
Laravel アプリケーション内では、PHP 用の Algolia クライアント パッケージを使用します。
アルゴリアの設定方法
まず、アプリケーション用の Algolia PHP 検索クライアント パッケージをインストールする必要があります。
以下のコマンドを実行します。
composer require algolia/algoliasearch-client-php
次に、Algolia からのアプリケーション ID とシークレット API キーの資格情報を.envファイルに設定する必要があります。
Web ブラウザを使用して Algolia ダッシュボードに移動し、アプリケーション ID とシークレット API キーの認証情報を取得します。
左側のサイドバーの下部にある「設定」をクリックして、 「設定」ページに移動します。
次に、[設定] ページの[チームとアクセス]セクション内の[API キー]をクリックして、Algolia アカウントのキーを表示します。
[API キー] ページで、アプリケーション IDと管理 API キーの値をメモします。 これらの資格情報を使用して、Laravel アプリケーションと Algolia の間の接続を認証します。
コード エディターを使用して以下のコードを .env ファイルに追加し、プレースホルダーを対応する Algolia API シークレットに置き換えます。
ALGOLIA_APP_ID=APPLICATION_ID ALGOLIA_SECRET=ADMIN_API_KEY
また、 SCOUT_DRIVER
変数を以下のコードに置き換えて、値をmeilisearch
からalgolia
に変更します。 この値を変更すると、Scout に Algolia ドライバーを使用するように指示されます。
SCOUT_DRIVER=algolia
アプリケーション コントローラーの作成方法
app/Http/Controllers/ディレクトリ内に、アプリケーションのコントローラーを保存するTrainSearchController.phpファイルを作成します。 コントローラーはデータをリストし、 Train
モデルに追加します。
次のコード ブロックをTrainSearchController.phpファイルに追加して、コントローラーを構築します。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Models\Train; class TrainSearchController extends Controller { /** * Get the index name for the model. * * @return string */ public function index(Request $request) { if($request->has('titlesearch')){ $trains = Train::search($request->titlesearch) ->paginate(6); }else{ $trains = Train::paginate(6); } return view('Train-search',compact('trains')); } /** * Get the index name for the model. * * @return string */ public function create(Request $request) { $this->validate($request,['title'=>'required']); $trains = Train::create($request->all()); return back(); } }
アプリケーションルートの作成方法
このステップでは、新しい列車をリストしてデータベースに追加するためのルートを作成します。
Routes/web.phpファイルを開き、既存のコードを以下のブロックに置き換えます。
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\TrainSearchController; Route::get('/', function () { return view('welcome'); }); Route::get('trains-lists', [TrainSearchController::class, 'index']) -> name ('trains-lists'); Route::post('create-item', [TrainSearchController::class, 'create']) -> name ('create-item');
上記のコードは、アプリケーション内で 2 つのルートを定義します。 /trains-lists
ルートのGET
リクエストは、保存されているすべての列車データをリストします。 /create-item
ルートのPOST
リクエストは、新しい列車データを作成します。
アプリケーションビューの作成方法
resource/views/ディレクトリ内にファイルを作成し、 Train-search.blade.phpという名前を付けます。 このファイルには、検索機能のユーザー インターフェイスが表示されます。
以下のコード ブロックの内容をTrain-search.blade.phpファイルに追加して、検索機能用の単一ページを作成します。
<!DOCTYPE html> <html> <head> <title>Laravel - Laravel Scout Algolia Search Example</title> <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> </head> <body> <div class="container"> <h2 class="text-bold">Laravel Full-Text Search Using Scout </h2><br/> <form method="POST" action="{{ route('create-item') }}" autocomplete="off"> @if(count($errors)) <div class="alert alert-danger"> <strong>Whoops!</strong> There is an error with your input. <br/> <ul> @foreach($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="row"> <div class="col-md-6"> <div class="form-group {{ $errors->has('title') ? 'has-error' : '' }}"> <input type="text" name="title" class="form-control" placeholder="Enter Title" value="{{ old('title') }}"> <span class="text-danger">{{ $errors->first('title') }}</span> </div> </div> <div class="col-md-6"> <div class="form-group"> <button class="btn btn-primary">Create New Train</button> </div> </div> </div> </form> <div class="panel panel-primary"> <div class="panel-heading">Train Management</div> <div class="panel-body"> <form method="GET" action="{{ route('trains-lists') }}"> <div class="row"> <div class="col-md-6"> <div class="form-group"> <input type="text" name="titlesearch" class="form-control" placeholder="Enter Title For Search" value="{{ old('titlesearch') }}"> </div> </div> <div class="col-md-6"> <div class="form-group"> <button class="btn btn-primary">Search</button> </div> </div> </div> </form> <table class="table"> <thead> <th>Id</th> <th>Train Title</th> <th>Creation Date</th> <th>Updated Date</th> </thead> <tbody> @if($trains->count()) @foreach($trains as $key => $item) <tr> <td>{{ ++$key }}</td> <td>{{ $item->title }}</td> <td>{{ $item->created_at }}</td> <td>{{ $item->updated_at }}</td> </tr> @endforeach @else <tr> <td colspan="4">No train data available</td> </tr> @endif </tbody> </table> {{ $trains->links() }} </div> </div> </div> </body> </html>
上記の HTML コードには、データベースに保存する前に列車のタイトルを入力するための入力フィールドとボタンを備えたフォーム要素が含まれています。 このコードには、データベース内の列車エントリのid 、 title 、 created_at 、およびupdated_at の詳細を表示する HTML テーブルもあります。
アルゴリア検索の使用方法
このページを表示するには、Web ブラウザから http://127.0.0.1:8000/trains-lists に移動します。
データベースは現在空であるため、入力フィールドにデモ列車のタイトルを入力し、 [新しい列車の作成]をクリックして保存する必要があります。
検索機能を使用するには、保存されている列車タイトルのキーワードを[検索するタイトルを入力してください] 入力フィールドに入力し、 [検索]をクリックします。
下の画像に示すように、タイトルにキーワードを含む検索エントリのみが表示されます。
Laravel Scout を使用した Meilisearch
Meilisearch は、速度、パフォーマンス、開発者エクスペリエンスの向上に重点を置いたオープンソースの検索エンジンです。 同じアルゴリズム、データ構造、研究を使用し、いくつかの機能を Algolia と共有していますが、使用しているプログラミング言語が異なります。
開発者は、オンプレミスまたはクラウド インフラストラクチャ内で Meilisearch インスタンスを作成し、自己ホストできます。 Meilisearch は、インフラストラクチャを管理せずに製品を使用したい開発者向けに、Algolia と同様のベータ クラウド サービスも提供しています。
このチュートリアルでは、Docker コンテナ内で Meilisearch のローカル インスタンスがすでに実行されています。 次に、Meilisearch インスタンスを使用するように Laravel Scout 機能を拡張します。
Meilisearch を Laravel アプリケーションに追加するには、プロジェクト ターミナルで以下のコマンドを実行します。
composer require meilisearch/meilisearch-php
次に、 .envファイル内の Meilisearch 変数を変更して構成する必要があります。
.envファイル内のSCOUT_DRIVER
、 MEILISEARCH_HOST
、およびMEILISEARCH_KEY
変数を以下のものに置き換えます。
SCOUT_DRIVER=meilisearch MEILISEARCH_HOST=http://127.0.0.1:7700 MEILISEARCH_KEY=LockKey
SCOUT_DRIVER
キーは Scout が使用するドライバーを指定し、 MEILISEARCH_HOST
Meilisearch インスタンスが実行されているドメインを表します。 開発時には必須ではありませんが、運用環境ではMEILISEARCH_KEY
を追加することをお勧めします。
注: Meilisearch を優先ドライバーとして使用する場合は、Algolia ID と Secret をコメント化します。
.env構成が完了したら、以下の Artisan コマンドを使用して既存のレコードにインデックスを付ける必要があります。
php artisan scout:import "App\Models\Train"
Laravel Scoutとデータベースエンジン
Scout のデータベース エンジンは、小規模なデータベースを使用するアプリケーションや、それほど負荷がかからないワークロードを管理するアプリケーションに最適です。 現在、データベース エンジンは PostgreSQL と MySQL をサポートしています。
このエンジンは、「where-like」句と既存のデータベースに対する全文インデックスを使用して、最も関連性の高い検索結果を見つけることができます。 データベース エンジンを使用する場合、レコードにインデックスを付ける必要はありません。
データベース エンジンを使用するには、 SCOUT_DRIVER
.env変数をデータベースに設定する必要があります。
Laravel アプリケーション内で.envファイルを開き、 SCOUT_DRIVER
変数の値を変更します。
SCOUT_DRIVER = database
ドライバーをデータベースに変更すると、Scout は全文検索にデータベース エンジンの使用に切り替えます。
Laravel Scoutを使用したコレクションエンジン
データベース エンジンに加えて、Scout はコレクション エンジンも提供します。 このエンジンは、「where」句とコレクション フィルタリングを使用して、最も関連性の高い検索結果を抽出します。
データベース エンジンとは異なり、コレクション エンジンは、Laravel もサポートするすべてのリレーショナル データベースをサポートします。
コレクション エンジンを使用するには、 SCOUT_DRIVER
環境変数をcollection
に設定するか、Scout 構成ファイルでコレクション ドライバーを手動で指定します。
SCOUT_DRIVER = collection
Elasticsearch を使用したエクスプローラー
Elasticsearch クエリの強力な機能を備えた Explorer は、Laravel Scout 用の最新の Elasticsearch ドライバーです。 互換性のある Scout ドライバーを提供し、大量のデータをリアルタイムで保存、検索、分析するなどの利点を提供します。 Laravel を使用した Elasticsearch では、ミリ秒単位で結果が得られます。
Laravel アプリケーションで Elasticsearch Explorer ドライバーを使用するには、Laravel-Scout スクリプトが生成したボイラープレートdocker-compose.ymlファイルを構成する必要があります。 Elasticsearch の追加構成を追加し、コンテナーを再起動します。
docker-compose.ymlファイルを開き、その内容を次のものに置き換えます。
# For more information: https://laravel.com/docs/sail version: '3' services: laravel.test: build: context: ./vendor/laravel/sail/runtimes/8.1 dockerfile: Dockerfile args: WWWGROUP: '${WWWGROUP}' image: sail-8.1/app extra_hosts: - 'host.docker.internal:host-gateway' ports: - '${APP_PORT:-80}:80' - '${VITE_PORT:-5173}:${VITE_PORT:-5173}' environment: WWWUSER: '${WWWUSER}' LARAVEL_SAIL: 1 XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}' XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}' volumes: - '.:/var/www/html' networks: - sail depends_on: - mysql - redis - meilisearch - mailhog - selenium - pgsql - elasticsearch mysql: image: 'mysql/mysql-server:8.0' ports: - '${FORWARD_DB_PORT:-3306}:3306' environment: MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}' MYSQL_ROOT_HOST: "%" MYSQL_DATABASE: '${DB_DATABASE}' MYSQL_USER: '${DB_USERNAME}' MYSQL_PASSWORD: '${DB_PASSWORD}' MYSQL_ALLOW_EMPTY_PASSWORD: 1 volumes: - 'sail-mysql:/var/lib/mysql' - './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh' networks: - sail healthcheck: test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}"] retries: 3 timeout: 5s elasticsearch: image: 'elasticsearch:7.13.4' environment: - discovery.type=single-node ports: - '9200:9200' - '9300:9300' volumes: - 'sailelasticsearch:/usr/share/elasticsearch/data' networks: - sail kibana: image: 'kibana:7.13.4' environment: - elasticsearch.hosts=http://elasticsearch:9200 ports: - '5601:5601' networks: - sail depends_on: - elasticsearch redis: image: 'redis:alpine' ports: - '${FORWARD_REDIS_PORT:-6379}:6379' volumes: - 'sail-redis:/data' networks: - sail healthcheck: test: ["CMD", "redis-cli", "ping"] retries: 3 timeout: 5s pgsql: image: 'postgres:13' ports: - '${FORWARD_DB_PORT:-5432}:5432' environment: PGPASSWORD: '${DB_PASSWORD:-secret}' POSTGRES_DB: '${DB_DATABASE}' POSTGRES_USER: '${DB_USERNAME}' POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}' volumes: - 'sailpgsql:/var/lib/postgresql/data' networks: - sail healthcheck: test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}"] retries: 3 timeout: 5s meilisearch: image: 'getmeili/meilisearch:latest' ports: - '${FORWARD_MEILISEARCH_PORT:-7700}:7700' volumes: - 'sail-meilisearch:/meili_data' networks: - sail healthcheck: test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"] retries: 3 timeout: 5s mailhog: image: 'mailhog/mailhog:latest' ports: - '${FORWARD_MAILHOG_PORT:-1025}:1025' - '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025' networks: - sail selenium: image: 'selenium/standalone-chrome' extra_hosts: - 'host.docker.internal:host-gateway' volumes: - '/dev/shm:/dev/shm' networks: - sail networks: sail: driver: bridge volumes: sail-mysql: driver: local sail-redis: driver: local sail-meilisearch: driver: local sailpgsql: driver: local sailelasticsearch: driver: local
次に、以下のコマンドを実行して、 docker-compose.ymlファイルに追加した新しい Elasticsearch イメージをプルします。
docker-compose up
次に、以下の Composer コマンドを実行して、エクスプローラーをプロジェクトにインストールします。
composer require jeroen-g/explorer
Explorer ドライバー用の構成ファイルを作成する必要もあります。
以下の Artisan コマンドを実行して、構成を保存するためのexplorer.configファイルを生成します。
php artisan vendor:publish --tag=explorer.config
上記で生成された構成ファイルは、 /configディレクトリで使用できます。
config/explorer.phpファイルでは、 indexes
キーを使用してモデルを参照できます。
'indexes' => [ \App\Models\Train::class ],
.envファイル内のSCOUT_DRIVER
変数の値をelastic
に変更して、Scout が Explorer ドライバーを使用するように構成します。
SCOUT_DRIVER = elastic
この時点で、Explorer インターフェイスを実装し、 mappableAs()
メソッドをオーバーライドすることで、 Train
モデル内で Explorer を使用します。
App > Modelsディレクトリ内のTrain.phpファイルを開き、既存のコードを以下のコードに置き換えます。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use JeroenG\Explorer\Application\Explored; use Laravel\Scout\Searchable; class Train extends Model implements Explored { use HasFactory; use Searchable; protected $fillable = ['title']; public function mappableAs(): array { return [ 'id'=>$this->Id, 'title' => $this->title, ]; } }
上で追加したコードを使用すると、エクスプローラーを使用してTrain
モデル内のテキストを検索できるようになります。
まとめ
PHP 開発者にとって、Laravel と Scout などのアドオンを使用すると、高速で堅牢な全文検索機能を簡単に統合できます。 データベース エンジン、コレクション エンジン、Meilisearch および Elasticsearch の機能を使用すると、アプリのデータベースと対話し、高度な検索メカニズムをわずか数ミリ秒で実装できます。
データベースのシームレスな管理と更新は、コードがクリーンで効率的な状態を保ちながら、ユーザーが最適なエクスペリエンスを享受できることを意味します。
Kinstaは、アプリケーションおよびデータベースホスティングソリューションを備えており、最新のLaravel開発ニーズをすべて満たすワンストップショップです。 最初の 20 ドルは私たちの負担です。