「Laravel Scout」でElasticsearchを使ってみる

「Laravel Scout」でElasticsearchを使ってみる

エリカ

エリカ

こんにちは、エリカです。

今回は、Laravelで全文検索を実装するアプローチについてです。全文検索といえば、とにかく情報量が多そうな Elasticsearch が候補のひとつになるかと思います。

それでは、Laravel から Elasticsearch をどのように扱えばいいのでしょうか。

Laravelの公式パッケージに、Laravel Scout があります。

Laravel Scout(スカウト、斥候)は、Eloquentモデルへ、シンプルなドライバベースのフルテキストサーチを提供します。モデルオブサーバを使い、Scoutは検索インデックスを自動的にEloquentレコードと同期します。
現在、ScoutはAlgoliaドライバを用意しています。カスタムドライバは簡単に書けますので、独自の検索を実装し、Scoutを拡張できます。

この Laravel Scout を利用して、Elasticsearch を利用するところまでを試してみます。

Elasticsearchの準備

まずは、手元で、 Elasticsearch を動かしておきます。Laradockなら elasticsearch コンテナを起動するだけです。簡単ですね。

docker-compose up -d elasticsearch

Laravelに必要パッケージのインストール

次に、 Laravelに必要なパッケージをインストールしていきます。

composer require laravel/scout
composer require elasticsearch/elasticsearch

laravel/scout がドライバベースの検索エンジンです。デフォルトのドライバとして algolia が用意されているのみですので、これを elasticsearch を利用するドライバに置き換えていきます。

設定ファイルの準備

検索用の設定ファイルを準備します。artisan コマンドを使えば、自動で作成できます。

php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

そうして作成された config/scout.php に下記のようにインデックス名やホスト名を追加しておきます。

'elasticsearch' => [
        'index' => env('ELASTICSEARCH_INDEX', 'scout'),
        'hosts' => [
            env('ELASTICSEARCH_HOST', 'http://localhost'),
        ],
    ],

.env ファイルで、 ELASTICSEARCH_HOST を指定します。また、検索エンジンも elasticsearch を利用するように指定します。

SCOUT_DRIVER=elasticsearch
ELASTICSEARCH_HOST=http://elasticsearch

ただ、この時点では、 elasticsearch という検索ドライバは存在していませんので、それを作成します。

Elasticsearchを扱うLaravel Scoutドライバの作成

それでは、 Elasticsearch を扱う検索ドライバを Scout に追加します。

まずは、 app/Scout/ElasticsearchEngine.php を作成します。

<?php

namespace App\Scout;

use Elasticsearch\Client as Elastic;
use Laravel\Scout\Builder;
use Laravel\Scout\Engines\Engine;

class ElasticsearchEngine extends Engine
{
    protected $elastic;
    protected $index;

    public function __construct(Elastic $elastic, $index)
    {
        $this->elastic = $elastic;
        $this->index = $index;
    }

    public function update($models)
    {
        // TODO: Implement update() method.
    }

    public function delete($models)
    {
        // TODO: Implement delete() method.
    }

    public function search(Builder $builder)
    {
        // TODO: Implement search() method.
    }

    public function paginate(Builder $builder, $perPage, $page)
    {
        // TODO: Implement paginate() method.
    }

    public function mapIds($results)
    {
        // TODO: Implement mapIds() method.
    }

    public function map(Builder $builder, $results, $model)
    {
        // TODO: Implement map() method.
    }

    public function getTotalCount($results)
    {
        // TODO: Implement getTotalCount() method.
    }

    public function flush($model)
    {
        // TODO: Implement flush() method.
    }
}

作成したドライバの登録

次に、ElasticsearchServiceProvider.phpを用意し、先ほど作成した、 Elasticsearch エンジンを elasticsearch という検索ドライバ名で利用できるようにします。

<?php

namespace App\Providers;

use App\Scout\ElasticsearchEngine;
use Elasticsearch\ClientBuilder;
use Illuminate\Support\ServiceProvider;
use Laravel\Scout\EngineManager;

class ElasticsearchServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        resolve(EngineManager::class)->extend('elasticsearch', function ($app) {
            return new ElasticsearchEngine(
                ClientBuilder::fromConfig([
                    'hosts' => config('scout.elasticsearch.hosts'),
                ]),
                config('scout.elasticsearch.index')
            );
        });
    }

    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

EloquentとLaravel Scoutの同期

EloquentにSearchableトレイトを指定すると、Eloquentの各種イベントで検索エンジンドライバのメソッドが自動的に呼び出されるようになります。

class Post extends Model
{
    use Searchable;
}

たとえば、Post::create() などの更新処理が行われた場合は、 ElasticsearchEngine::update() が呼び出されます。

あとは、ElasticsearchEngine の各メソッドでどのようなデータのやりとりを行なっていくかの記述をしていけばいいだけです。

まとめ

Elasticsearchとの連携もLaravelなら簡単ですね。

LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。

Webサイト制作の実績・料金を見る

この記事のシェア数

ディレクターのエリカです。趣味は美術鑑賞で、絵画や展示などたくさんの作品を眺めるのが好きです。得意料理は「鍋」です。よろしくお願いします。

このメンバーの記事をもっと読む
バックエンドへの道 | 58 articles
デザイン力×グローバルな開発体制でDXをトータル支援
お問い合わせ 会社概要DL