Table of Contents |
---|
Note |
---|
laravel 5.3 에 도입된 scout 패키지를 사용하여 full text search engine 연계하는 방법에 대해 설명합니다. |
...
scout elastic search 패키지를 설치합니다.
Code Block language bash title laravel 6.x $ composer require babenkoivan/scout-elasticsearch-driver
Code Block language bash title laravel 5.8 $ composer require babenkoivan/scout-elasticsearch-driver "^3.0"
Note 만약 ES 6을 사용한다면 3.12 버전을 설치해 줍니다.
config/app.php 의 providers 에 프로바이더를 추가합니다. 개인적으로는 Laravel 의 Package Discovery 기능을 별로 좋아하지 않아서 직접 추가하는 것이며 추가해 주는데 등록해 주지 않아도 최신 버전의 라라벨에서는 정상 동작합니다.
Code Block 'providers' => [ Laravel\Scout\ScoutServiceProvider::class, ScoutElastic\ScoutElasticServiceProvider::class, ]
config에 설정 파일을 생성하기 위해 vendor publish 수행합니다.
Code Block php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider" php artisan vendor:publish --provider="ScoutElastic\ScoutElasticServiceProvider"
- 컨피그 파일(config/scout_elastic.php) 설정 변경이 필요하면 수정합니다.
.env 에 다음 내용을 추가합니다.
Code Block SCOUT_DRIVER=elasticsearchelastic ## laravel scout host SCOUT_ELASTIC_HOST=localhost:80
Warning - nginx 를 붙여서 사용할 경우 SCOUT_ELASTIC_HOST 에 포트를 명시해야 합니다.(기본 9200)
- URL 뒤에 trailing slash(Ex: my.site:80/) 를 붙이면 오작동하므로 주의하세요!
Queue 를 사용하여 인덱싱할 경우 config/scout.php 의 다음 항목을 true 로 설정합니다.
Code Block 'queue' => true,
...
Code Block | ||||
---|---|---|---|---|
| ||||
<?php namespace App; use ScoutElastic\IndexConfigurator; use ScoutElastic\Migratable; class UserIndexConfigurator extends IndexConfigurator { use Migratable; // index 이름을 직접 설정하려면 $name 변수에 이름을 지정해 주면 됩니다. // 생략할 경우 `IndexConfigurator` 를 제외한 snaked class 이름으로 생성됩니다. protected $name = 'user_index'; // You can specify any settings you want, for example, analyzers. protected $settings = [ 'analysis' => [ "tokenizer" => [ "nori_user_dict" => [ "type" => "nori_tokenizer", "decompound_mode" => "mixed", "user_dictionary" => "userdict_ko.txt" ] ], 'analyzer' => [ 'my_analyzer' => [ 'type' => 'custom', "tokenizer" => "nori_user_dict" ] ] ] ]; // ES field 매핑 protected $defaultMapping = [ 'properties' => [ "id"=> [ "type"=> "long" ], "name"=> [ "type"=> "text", "analyzer"=> "koreanmy_analyzer", "search_analyzer"=> "koreanmy_analyzer" ], "email"=> [ "type"=> "text", "analyzer"=> "koreanmy_analyzer", "search_analyzer"=> "koreanmy_analyzer" ], "created_at"=> [ "type"=> "date", "format"=> "yyyy-MM-dd HH:mm:ss" ], "updated_at"=> [ "type"=> "date", "format"=> "yyyy-MM-dd HH:mm:ss" ], ] // properties ]; } |
...
localhost:9200/my_index 에 연결해서 인덱스가 생겼는지 확인해 봅니다.
...
Searchable Data
기본적으로 모델의 toArray() 를 호출한 결과를 인덱싱하므로 커스터마이징할 경우 toSearchableArray() 메서드 구현
...
검색 가능하게 Model 모델 설정
Model class 와 ES 연동은 간단하게 Searchable trait 을 추가하고 $indexConfigurator 변수에 사용할 IndexConfigurator 만 등록해 주면 됩니다.
주의할 점은 Searchable trait 은 Laravel\Scout\Searchable 이 아닌 ScoutElastic\Searchable 을 사용해야 합니다.
Code Block | ||
---|---|---|
| ||
<?php class MyModel extends Model { use Searchable; /** * Get the indexable data array for the model. * * @return array */ public function toSearchableArray() { $array = $this->toArray(); // Customize array... // Laravel\Scout\Searchable을 사용하지 않도록 주의 use \ScoutElastic\Searchable; // 사용할 index protected $indexConfigurator return $array; } }= MyIndexConfigurator::class; |
indexing
Batch indexing
scout:import artisan 명령으로 현재 모델을 모델 데이타를 배치로 인덱싱할 수 있음있습니다.
Code Block |
---|
$ php artisan scout:import "App\UserMyModel" |
Record 추가
Laravel\Scout\Searchable 트레이트를 추가한 모델은 save() 메서드 호출시 자동으로 인덱싱인덱싱됩니다.
Code Block |
---|
$order = new App\Order; // ... $order->save(); |
...
또는 명시적으로 searchable() 메서드를 호출하면 인덱싱됨인덱싱이 됩니다.
Code Block |
---|
// Adding via Eloquent query... App\Order::where('price', '>', 100)->searchable(); // You may also add records via relationships... $user->orders()->searchable(); // You may also add records via collections... $orders->searchable(); |
elastic search 새로운 indexing 생성
Code Block |
---|
$ curl -XPUT 'localhost:9200/laravel?pretty' |
2번째
Code Block |
---|
$ curl 'localhost:9200/_cat/indices?v' |
Faker로 테스트 데이타 생성
...
테스트 데이타 생성
실제 테스트를 위해 Faker 로 Model factory 를 생성하고 indexing 해 보겠습니다.
테스트용 테이블을 만들기 위한 새로운 migration 생성합니다.
Code Block $ php artisan make:migration --table=userscompany add_company_on_users_table
User 테이블에 컬럼 추가컬럼을 추가합니다.
Code Block public function up() { Schema::table('users', function (Blueprint $table) { $table->string('company', 50); $table->string('address', 100); $table->string('phoneNumber', 50); }); } public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('company'); $table->dropColumn('address'); $table->dropColumn('phoneNumber'); }); }
migration 실행실행합니다.
Code Block $ php artisan migrate
database/factories/ModelFactory.php 수정 수정합니다.
Code Block $factory->define(App\User::class, function (Faker\Generator $faker) { static $password; // 한글 로캘 적용된 Faker 팩토리 생성 $koFaker = \Faker\Factory::create('ko_KR'); return [ 'name' => $koFaker->name, 'company' => $koFaker->company, 'address' => $koFaker->address, 'phoneNumber' => $koFaker->phoneNumber, 'email' => $faker->unique()->companyEmail, 'password' => $password ?: $password = bcrypt('secret'), 'remember_token' => str_random(10), ]; });
팅커 구동
Code Block $ php artisan tinker
테스트용 모델 팩토리 생성
Code Block >>> factory('App\User', 300)->create();
검색
Code Block >>> $us = App\User::search('민')->get();
...