/elastic_search_laravel_2021

Elastic search 7 implementation in laravel 8 latest 2021

Primary LanguagePHP

elastic_search_laravel_2021

Elastic Search ver 7 with Laravel 8

composer require elasticsearch/elasticsearch

composer require laravel/breeze --dev

For Dashboard UI

php artisan breeze:install

npm install

npm run dev

php artisan migrate

artisan make:model -mf Article

code Schema::create('articles', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('body'); $table->json('tags'); $table->timestamps(); });

'json', ]; } times(50)->create(); } } $this->faker->sentence(), 'body' => $this->faker->text(), 'tags' => collect(['php', 'ruby', 'java', 'javascript', 'bash']) ->random(2) ->values() ->all(), ]; } } ### Update view dashboard.php

{{ __('Articles') }} ({{ $articles->count() }})

@if (request()->has('q'))

Using search: "{{ request('q') }}". Clear filters

@endif
@forelse ($articles as $article)

{{ $article->title }}

{{ $article->body }}

@foreach ($article->tags as $tag) {{ $tag}} @endforeach
@empty

No articles found

@endforelse
where(fn ($query) => ( $query->where('body', 'LIKE', "%{$term}%") ->orWhere('title', 'LIKE', "%{$term}%") )) ->get(); } } use App\Articles\SearchRepository; Route::get('/dashboard', function (SearchRepository $searchRepository) { return view('dashboard', [ 'articles' => request()->has('q') ? $searchRepository->search(request('q')) : App\Models\Article::all(), ]); })->middleware(['auth'])->name('dashboard'); elasticSearchIndex($this->elasticsearchClient); } public function deleted($model) { $model->elasticSearchDelete($this->elasticsearchClient); } } index([ 'index' => $this->getTable(), 'type' => '_doc', 'id' => $this->getKey(), 'body' => $this->toElasticsearchDocumentArray(), ]); } public function elasticsearchDelete(Client $elasticsearchClient) { $elasticsearchClient->delete([ 'index' => $this->getTable(), 'type' => '_doc', 'id' => $this->getKey(), ]); } abstract public function toElasticsearchDocumentArray(): array; } elasticsearch = $elasticsearch; } public function search(string $query = ''): Collection { $items = $this->searchOnElasticsearch($query); return $this->buildCollection($items); } private function searchOnElasticsearch(string $query = ''): array { $model = new Article; $items = $this->elasticsearch->search([ 'index' => $model->getSearchIndex(), 'type' => $model->getSearchType(), 'body' => [ 'query' => [ 'multi_match' => [ 'fields' => ['title^5', 'body', 'tags'], 'query' => $query, ], ], ], ]); return $items; } private function buildCollection(array $items): Collection { $ids = Arr::pluck($items['hits']['hits'], '_id'); return Article::findMany($ids) ->sortBy(function ($article) use ($ids) { return array_search($article->getKey(), $ids); }); } } app->bind(Articles\ArticlesRepository::class, function ($app) { // This is useful in case we want to turn-off our // search cluster or when deploying the search // to a live, running application at first. if (! config('services.search.enabled')) { return new Articles\EloquentRepository(); } return new Articles\ElasticsearchRepository( $app->make(Client::class) ); }); } } app->bind(Articles\ArticlesRepository::class, function () { // This is useful in case we want to turn-off our // search cluster or when deploying the search // to a live, running application at first. if (! config('services.search.enabled')) { return new Articles\EloquentRepository(); } return new Articles\ElasticsearchRepository( $app->make(Client::class) ); }); $this->bindSearchClient(); } private function bindSearchClient() { $this->app->bind(Client::class, function ($app) { return ClientBuilder::create() ->setHosts($app['config']->get('services.search.hosts')) ->build(); }); } } ### Update config /services.php [ 'enabled' => env('ELASTICSEARCH_ENABLED', false), 'hosts' => explode(',', env('ELASTICSEARCH_HOSTS')), ], ]; ### Add to .ENV file ELASTICSEARCH_ENABLED=true ELASTICSEARCH_HOSTS="localhost:9200" elasticsearch = $elasticsearch; } public function handle() { $this->info('Indexing all articles. This might take a while...'); foreach (Article::cursor() as $article) { $this->elasticsearch->index([ 'index' => $article->getSearchIndex(), 'type' => $article->getSearchType(), 'id' => $article->getKey(), 'body' => $article->toSearchArray(), ]); // PHPUnit-style feedback $this->output->write('.'); } $this->info("\nDone!"); } } ### CLI php artisan make:command ReindexCommand --command="search:reindex" ### Advance [ 'multi_match' => [ 'fields' => ['title^5', 'body', 'tags'], 'query' => $query, ], ],