AppDividend
Latest Code Tutorials

Laravel Elasticsearch Tutorial Example From Scratch

4,945

Get real time updates directly on you device, subscribe now.

Laravel Elasticsearch Tutorial Example From Scratch is the today’s leading topic. For this example, we use the composer package called ElasticquentIt is called Elasticsearch for Eloquent Laravel Models. Elasticquent makes working with Elasticsearch and Eloquent models easier by mapping them to Elasticsearch types. You can use the default settings or define how Elasticsearch should index and search your Eloquent models right in the model. The Elasticquent allows you take an Eloquent model and easily index and search its contents in Elasticsearch. Okay, let us start the Laravel Elasticsearch Tutorial Example.

Laravel Elasticsearch Tutorial Example

We begin this example by install Elasticsearch on the mac and then set up the laravel development environment.

#Step 1: Install Elasticsearch on Mac.

If you have not previously installed Elasticsearch on the mac then you need this step otherwise you can skip this step.  Type the following cmd in your terminal to install Elasticsearch via homebrew.

brew install elasticsearch

It will install it and now start the services using the following command.

brew services start elasticsearch

#Step 2: Setup Laravel and Elasticsearch env.

Install Laravel 5.6 by the following command.

laravel new elasticlaravel

Go into the project folder.

cd elasticlaravel

Open the project in your editor.

code .

Configure the database inside the .env file.

Add the following line inside the composer.json file. We are installing Elasticquent package.

"require": {
        "php": "^7.1.3",
        "fideloper/proxy": "^4.0",
        "laravel/framework": "5.6.*",
        "laravel/tinker": "^1.0",
        "elasticquent/elasticquent": "dev-master"
    },

Type the following command to install the elasticquent package.

composer update

 

Laravel Elasticsearch Tutorial Example

Once you’ve run a composer update command, you need to register Laravel service provider, in your config/app.php file.

// config/app.php

'providers' => [
    ...
    Elasticquent\ElasticquentServiceProvider::class,
],

We also provide a facade for an elasticsearch-php client (which has connected using our settings), add following to your config/app.php if you need so.

// config/app.php

'aliases' => [
    ...
    'Es' => Elasticquent\ElasticquentElasticsearchFacade::class,
],

#Elasticsearch Configuration

Type the following Artisan command to publish the configuration file into your config directory for Laravel 5.6.

php artisan vendor:publish --provider="Elasticquent\ElasticquentServiceProvider"

Now go to the config file at app >> config >> elastiquent.php

We need to add the index name for our application. So let us change from default to articles.

<?php

// elastiquent.php

return array(

    /*
    |--------------------------------------------------------------------------
    | Custom Elasticsearch Client Configuration
    |--------------------------------------------------------------------------
    |
    | This array will be passed to the Elasticsearch client.
    | See configuration options here:
    |
    | http://www.elasticsearch.org/guide/en/elasticsearch/client/php-api/current/_configuration.html
    */

    'config' => [
        'hosts'     => ['localhost:9200'],
        'retries'   => 1,
    ],

    /*
    |--------------------------------------------------------------------------
    | Default Index Name
    |--------------------------------------------------------------------------
    |
    | This is the index name that Elasticquent will use for all
    | Elasticquent models.
    */

    'default_index' => 'articles',

);

#Step 3: Create an Article model and migration.

We will search the articles using elasticsearch. To create a model and migration using the following command.

php artisan make:model Article -m

In your <DATETIME>_create_articles_table.php file add the schema code.

// create_articles_table.php

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

Migrate the table using the following command.

php artisan migrate

#Step 4: Create the dummy data.

Create an ArticleTableSeeder using the following command.

php artisan make:seeder ArticleTableSeeder

For generating the fake data, we use Faker library. However, before that, we need to add the protected $fillable fields inside Article.php file to prevent the mass assignment exception.

Related Posts
1 of 39
// Article.php

class Article extends Model
{
    protected $fillable = ['title', 'body', 'tags'];
}

Now, add the following code inside ArticleTableSeeder.php file.

<?php

// ArticleTableSeeder.php

use Illuminate\Database\Seeder;
use App\Article;

class ArticleTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $faker = Faker\Factory::create();

        for($i=0; $i<50; $i++) {
          Article::create([
            'title' => $faker->sentence(3),
            'body' => $faker->paragraph(6),
            'tags' => join(',', $faker->words(4))
          ]);
        }
    }
}

Add the ArticleTableSeeder class inside DatabaseSeeder.php file which is located in the same directory.

<?php

// DatabaseSeeder.php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(ArticleTableSeeder::class);
    }
}

Okay, now run the seeder and create the fake data using the following command.

php artisan db:seed

 

Elasticsearch in Laravel

#Step 5: Set up Elastiquent inside Article model.

Write the following code inside Article.php file.

<?php

// Article.php

namespace App;
use Elasticquent\ElasticquentTrait;

use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    use ElasticquentTrait;

    protected $fillable = ['title', 'body', 'tags'];

    protected $mappingProperties = array(
        'title' => [
          'type' => 'text',
          "analyzer" => "standard",
        ],
        'body' => [
          'type' => 'text',
          "analyzer" => "standard",
        ],
        'tags' => [
          'type' => 'text',
          "analyzer" => "standard",
        ],
      );
}

Here, we add our mapping configuration for ElasticSearch. The database table has three main fields. So we need to assign the type and analyzer which in our case is standard. Remember, our index name is articles. The mappingProperties array is the fields that need to be indexed with the proper type to search and get the perfect results. Each mapping has a kind and an analyzer. Type’s can be various data types including strings, numbers, and dates. For now, we will stick to the text type but be aware that different types allow you to take advantage of different things. You can find more datatype here at the original elasticsearch docs.

Okay, now we need to index the database. So inside web.php file, write the following code. Remember, I have written the following code inside web.php file but in a real-time scenario, you need to write this inside controller or any other logical part of your app except web.php file.

#Indexing Documents

To index all the entries in an Eloquent model, use addAllToIndex:

    Article::addAllToIndex();

You can also index a collection of models:

    $articles = Article::where('id', '<', 200)->get();
    $articles->addToIndex();

You can index individual entries as well:

    $articles = Article::find($id);
    $articles->addToIndex();

You can also reindex an entire model:

     Article::reindex()

Now, we index the whole model so that we can write the indexing code inside root route.

<?php

// web.php

use App\Article;

Route::get('/', function () {
    Article::createIndex($shards = null, $replicas = null);

    Article::putMapping($ignoreConflicts = true);

    Article::addAllToIndex();

    return view('welcome');
});

Here, we have created the index. The name of the index is already defined inside config >> elastiquent.php file.

Then we have put the mapping, which is defined in the Article.php model and finally adds that to the indexing.

Go to the browser and hit this URL: http://elasticlaravel.test/

You will get the welcome page, but our data is entirely indexed and we can verify that by sending the following request using cURL. We can also use the postman for that, but I am sending the request via terminal.

curl 'localhost:9200/articles/_mapping?pretty'

 

Elastic search api for laravel with example

We can do a basic search using the following command.

curl 'localhost:9200/articles/articles/_search?q=title:Sed&pretty'

Here, our search term for the title is Sed. So it will fetch the records that have Sed term. We can see the prettify results inside a terminal.

Laravel Elasticsearch query example

 

#Step 6: Search using Laravel eloquent methods.

Okay so till now, we have used cURL for the searching the data. Now, we will use Elastiquent method to search the data. So let us create another route inside the web.php file and add the following code in it.

<?php

// Article.php

use App\Article;

Route::get('/', function () {
    Article::createIndex($shards = null, $replicas = null);

    Article::putMapping($ignoreConflicts = true);

    Article::addAllToIndex();

    return view('welcome');
});

Route::get('/search', function() {

    $articles = Article::searchByQuery(['match' => ['title' => 'Sed']]);

    return $articles;
});

I have passed the ‘Sed’ hardcoded, but in a real-time application, it will be our search term which is typed inside the search box. Now, switch to this URL: http://elasticlaravel.test/search. You can see the JSON response like this.

Search using elasticsearch in Laravel

 

Of course, you might be getting different data because it is randomly generated data. So first check the database and pick the term and then pass to the search engine and it will return something like this. So we have successfully indexed the data and fetched the data from the elasticsearch engine.

In this example, we have searched for the title, you can go for body and tags as well.

$articles = Article::searchByQuery(['match' => ['body' => 'eligendi']]);
    
return $articles;

And you can do the same for the tags as well.

#Search collections

We can get the total hits to count using the following code.

$articles = Article::searchByQuery(['match' => ['title' => 'Heleium']]);
    
 return $articles->totalHits();

Access the shards array:

 $articles->shards();

Access the max score:

 $articles->maxScore();

Access the timed out boolean property:

 $articles->timedOut();

Access the took property:

  $articles->took();

Access search aggregations – See Aggregations for details:

  $articles->getAggregations();

#Chunking results from Elastiquent.

To get the results in chunks, you can use the chunk() function.

$articles = Article::searchByQuery(['match' => ['title' => 'Similique']]);
    
return $articles->chunk(2);

Finally, Laravel Elasticsearch Tutorial Example is over. Thanks for taking.

2 Comments
  1. Amit K Sharma says

    Why default_index required and what is the use of it, as I am confused little.

  2. Inna Tarasyan says

    Thanks, Great job

Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.