Basic Search Functionality with ElasticSearch & Laravel Scout

Samantha O'Gorman
Oct 13, 2016 · 4 min read

First things first, I’m a developer, not a writer. So, please excuse my grammar, punctuation and all that palaver.

Moving on…

Recently, I’ve been required to implement a full-text search function using Laravel and an open-source package called “ElasticSearch”. Having no idea where to start with this task, I did a quick search on Google and found something called “Elastiquent”. The documentation for this package is fairly brief and since I’m not (yet) a Laravel expert, I was a little intimidated on how to actually put this package in to real practice. I found a couple of tutorials on Google (when I say a couple, I literally mean two), these tutorials were outdated and slightly confusing to follow.

I spent two days and got nowhere.

I did some more “googling” and found that Laravel Scout now supports the ElasticSearch package. Again, the documentation for this is scarce and Laravel only seems to use Algolia (they must have a deal with Taylor) in their examples, same goes for Laracasts.

Anyway, here’s a nice little tutorial on how to get basic search functionality working with ElasticSearch and Laravel Scout.


Prerequisites


Installing the Required Packages and Including the Service Providers

Inside your terminal, you will need to run:

composer require laravel/scout

This will add the Laravel Scout package to your application and update the composer.json file.

Once that’s all fine and dandy, go ahead and run:

composer require tamayo/laravel-scout-elasticcomposer require elasticsearch/elasticsearch

Update your providers array inside config/app.php to include the Laravel Scout and the Scout Elastic Driver service providers:

Laravel\Scout\ScoutServiceProvider::class,
ScoutEngines\Elasticsearch\ElasticsearchProvider::class,

No errors so far? Cool. Let’s move on…


In my example, I’m going to use a Model called “Account”, but you can alter this as needed to match the model you wish to search.

Inside my model I add the Laravel Scout Searchable trait, like so:

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Account extends Model
{
use Searchable;
protected $fillable = [
'name'
];
public function user(){
return $this->belongsTo('App\User');
}
}

Now, navigate to config/scout.php and change this line:

‘driver’ => env(‘SCOUT_DRIVER’, ‘algolia’),

to this:

‘driver’ => env(‘SCOUT_DRIVER’, ‘elasticsearch’),

If you scroll down on that same page, you should see some driver configurations for Algolia and ElasticSearch, the ES one should look like this:

elasticsearch’ => [
‘index’ => env(‘ELASTICSEARCH_INDEX’, ‘laravel’),
‘config’ => [
‘hosts’ => [
env(‘ELASTICSEARCH_HOST’, ‘localhost’),
],
],
],

If it’s not there, you can just add the snippet from above.

Next, navigate to your .env file and add configuration settings for elasticsearch:

ELASTICSEARCH_INDEX=scout
ELASTICSEARCH_HOST=http://localhost:9200

Note: If you do not have a scout.php file inside your config folder, you can create one yourself and copy the contents from vendor/laravel/scout/config/scout.php (and obviously changing to the configuration to as stated above).


Now, you need to import the model you wish to search via scout.

Inside your terminal/command line, type:

php artisan scout:import “App\Account”

*remember to change the “App\Account” to the model you are using*

You should see a success message that tells you how many records it has returned.

Now to test if this is all working correctly, run:

php artisan tinker

and then run this:

App/Account::search(‘literallyanytextyouwantosearch’)->get();

If working correctly, it will return arrays of matching results in Json format.

Now, you’ll need to create a search controller, here’s how to do that (if you don’t already know)…inside the terminal:

php artisan make:controller SearchController

Now, navigate to that file inside your text editor, and include your model namespace:

use App\Account;

Then create a method inside the SearchController, like so:

public function search(Request $request){   if($request->has('search')){

$accounts = Account::search($request->input('search'))->get();
} return view('search.results', compact('accounts'));
}

Then navigate to your web.php file and add the following route:

Route::get('/SearchQuery', 'SearchController@search');

Now that’s the backend set up.


Now you need to create the views for the search bar and the results.

<form id="elasticScout" action="/SearchQuery" method="get">
<div class="mysearchbar">
<input name="search" placeholder="Search...">
</div>
</form>

In the search controller, I used “search.results” as the view to be returned when the method is called, so in this example, I would put the following into search/results.blade.php.

@if(!empty($accounts))    @foreach($accounts as $account)        <h1>{{ $account->name }} </h1>    @endforeach@endif

And there you go, if you’ve followed the steps you should have yourself a nice basic model search using Laravel Scout and ElasticSearch. I’m currently working on making an advanced search with this feature so I may post again in the near future.

Chow, friends.

P.s. Big thanks to Dario Peter for reminding me to add the Elastic Scout Driver to the tutorial and I apologise for the late fix.

Samantha O'Gorman

Written by

Junior Web Developer | Mediocre rock climber

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade