LoginSignup
14
7

More than 5 years have passed since last update.

Laravel Scout で AWSのElasticSearch を使う

Posted at

Eloquence が Laravel 5.4 に対応しないので検索機能を Scout+ElasticSearch に変更した記録。
5.3の頃にやろうとして失敗。
時間が経って情報が揃ってたのでやっと成功。
Scout も ElasticSearch も初めて使って基本的な検索機能ができた程度の記事。

バージョン

  • Laravel 5.4
  • Laravel Scout 3.0
  • ElasticSearch 5.1

使うもの

AWS以外ならこれだけでいいはず。
https://github.com/ErickTamayo/laravel-scout-elastic
AWSで使うなら一工夫必要なのでこれも。
READMEに書いてないけど composer require jsq/amazon-es-php
https://github.com/jeskew/amazon-es-php
情報元。Scout が標準で ElasticSearch 対応してた頃なので参考程度に。
http://stackoverflow.com/questions/40651963/laravel-scout-config-aws-elasticsearch-service
1.0にだけ ElasticsearchEngine.php がある。
https://github.com/laravel/scout/tree/1.0/src/Engines

AWS側の設定

認証部分はいくつか方法がありそうだけど今回のLaravelプロジェクトは Elastic Beanstalk で動かしてIAMユーザーの AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY を環境変数で設定してるのでユーザーで認証。

  • 新しい ElasticSearch を作る。
  • 使うIAMユーザーに AmazonESFullAccess を追加。

access policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::[AWS account ID]:user/[IAMuser]"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:ap-northeast-1:[AWS account ID]:domain/[domain]/*"
    },
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:ap-northeast-1:[AWS account ID]:domain/[domain]/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "x.x.x.x"
        }
      }
    }
  ]
}

Kibana使うために自分のIPだけ許可する。

Laravel側

laravel-scout-elastic と amazon-es-php を composerでインストールしたら
laravel-scout-elastic の ElasticsearchProvider.php を app/Providers/にコピーして書き換える。

<?php

namespace App\Providers;

use Laravel\Scout\EngineManager;
use Illuminate\Support\ServiceProvider;
use Elasticsearch\ClientBuilder as ElasticBuilder;

use ScoutEngines\Elasticsearch\ElasticsearchEngine;
use Aws\ElasticsearchService\ElasticsearchPhpHandler;

class ElasticsearchProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     */
    public function boot()
    {
        resolve(EngineManager::class)->extend('elasticsearch', function ($app) {
            $handler = new ElasticsearchPhpHandler(config('scout.elasticsearch.region'));

            return new ElasticsearchEngine(
                ElasticBuilder::create()
                              ->setHandler($handler)
                              ->setHosts(config('scout.elasticsearch.hosts'))
                              ->build(),
                config('scout.elasticsearch.index')
            );
        });
    }
}

config/app.phpには
App\Providers\ElasticsearchProvider::class,を登録。

ScoutEngines\Elasticsearch\ElasticsearchProvider::class,は不要。

config/scout.php

AWS_ACCESS_KEY_IDを見てるからかパスワードの設定とかなくても動いてる…。
この辺の仕組みはしっかり調べてない。
上の ElasticsearchPhpHandler が amazon-es-php でAWSの認証部分を上手くやってる。

    'elasticsearch' => [
        'index' => env('ELASTICSEARCH_INDEX', 'laravel'),
        'hosts' => [
            env('ELASTICSEARCH_HOST', 'http://localhost'),
        ],
        'region' => env('AWS_REGION', 'ap-northeast-1'),
    ],

.env

ローカル用はlocalとでも付けておく。
本番用は別途設定。

SCOUT_DRIVER=elasticsearch
ELASTICSEARCH_INDEX=***-local
ELASTICSEARCH_HOST=***.ap-northeast-1.es.amazonaws.com

Eloquent

どういうデータを登録するかはtoSearchableArray()でカスタマイズ。

初回インポート

ここまでできてるか確認のためimport。できなかったら設定見なおし。

php artisan scout:import "App\Post"

flushで全部削除。最初の内は登録と削除を繰り返すことになるはず…。

php artisan scout:flush "App\Post"

ここまでできたら

後は公式ドキュメントで十分。
https://laravel.com/docs/5.4/scout
https://readouble.com/laravel/5.4/ja/scout.html

その先には ElasticSearch と Kibana の 使い方を調べる作業が待ってる。

14
7
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
14
7