Utilizing Laravel Scout To Enable Full-Text Search - (r)

May 8, 2023
Learning laravel scout

Share the news on

As an open-source tool, Laravel offers a myriad of out-of-the-box functionalities that enable designers to create robust and functional applications.

Here, we will explore this tool in-depth, teaching the user how to add the full-text search feature to a Laravel application using the driver. You will model a demo Laravel application that stores the names of mockup trains and then make use of Laravel Scout to add an option to search the application.

Prerequisites

For following along for this, you'll need:

  • The PHP compiler installed on your computer. This tutorial uses PHP Version 8.1.
  • It is the Docker Engine or Docker Desktop can be installed on your PC
  • An Algolia cloud-based account that you can make for free

How to Install Scout within a Laravel Project

For you to utilize Scout it is necessary to develop an Laravel application that you want to add the search functionality. The script Laravel-Scout Bash contains the necessary commands for creating an Laravel application that is contained in a Docker container. Utilizing Docker implies that you do not need to install other applications, such as the MySQL database.

The Laravel-scout script uses an implementation of the Bash scripting language, so you must execute it within a Linux environment. If you're using Windows, ensure you configure Windows Subsystem to Linux (WSL).

If you're using WSL, execute the following command in your terminal to select your preference for Linux distribution.

wsl -s ubuntu

After that, you must navigate to the area where you'd like to save the project. The script created by Laravel-Scout will create the project directory on this page. The example below shows how the Laravel-Scout script would create a directory within this directory. desktop directory.

Cd desktop

Use the below command to start the Laravel-Scout program. This will create an Dockerized app by providing the boilerplate codes required.

curl -s https://laravel.build/laravel-scout-app | bash

Following the execution, you can change your directory using the cd command laravelscout. Then, run your sail-up command from within the folder for your project to begin the Docker containers that will run your app.

NOTE: On many Linux distributions, you might need to execute the following command by using your sudo command in order to gain elevated privileges.

./vendor/bin/sail up

You might encounter an error:

Error stating the port is allocated
Error stating the port is not allocated.

To resolve this, use the APP_PORT variable to define a port within sail up: sailing up command:

APP_PORT=3001 ./vendor/bin/sail up

Next, execute the command below to launch the application via Artisan to PHP. PHP server.

php artisan serve
Serving the Laravel application with Artisan
Supporting the Laravel application using Artisan

From your web browser, navigate to the running application at http://127.0.0.1:8000. The application will display your Laravel welcome page at the default URL.

Welcome page of the Laravel application
Welcome page of the Laravel application

How Do I Add Laravel Scout into the App

In your terminal, type this command to allow your Composer PHP module manager. This will enable Laravel Scout to the project.

composer require laravel/scout

Next, publish your Scout configuration file by using this command from the vendor. The command will publish your scout.php configuration file into your application's configuration directory.

 php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

Then, alter your boilerplate .env file to include an SCOUT_QUEUE variable that is a boolean.

SCOUT_QUEUE SCOUT_QUEUE value will allow Scout to hold operations in queue which will result in faster response times. Without it, Scout drivers like Meilisearch will not reflect any new data in a timely manner.

SCOUT_QUEUE=true
DB_HOST=127.0.0.1

How To Mark a Model and Configure the Index

Scout does not enable searchable models of data by default. You must explicitly mark a model as searchable using its Laravel\Scout\Searchable trait.

You'll start by creating the data model of a demo Train application and marking the model as searchable.

How to Create an Model

For for the Train application, it is necessary to keep the names that are placeholders for each available train.

Use the Artisan command to create the migration. Name it the table create_trains..

php artisan make:migration create_trains_table 
Making a migration named create_trains_table
Making a migration named create_trains_table

The data will be stored within a file that is a combination of the name you specify and the time stamp of the moment.

Navigate to the migration file in the database/migrationsdirectory. directory.

To include the title column, paste the following code after the Id() column in line 17. This code adds a title column.

$table->string('title');

To apply the migration, execute the command below.

php artisan migrate
Applying the Artisan migration
Utilizing the Artisan migration

After running the database migrations, create a file named Train.php in the model/app/ directory.

How To Add the LaravelScoutSearchable Trait

Mark the Train model for search by adding the Laravel\Scout\Searchable trait to the model, as shown below.

How to Use Algolia together with Scout

In order to perform your first full-text search that you can do with Laravel Scout, you'll use the Algolia driver. Algolia is a software as a service (SaaS) platform that allows you for searching through huge amounts of information. It provides a web dashboard for developers to manage their search indexes as well as an API with a strong interface that users can access through the Software Development Kit (SDK) using your favorite programming language.

In of the Laravel application, you'll use it with the Algolia client application for PHP.

How Do I Set Up Algolia

In the beginning, you need to install the Algolia PHP search client program for your application.

Follow the instructions below.

composer require algolia/algoliasearch-client-php

Next, you must set the Application ID and Secret API Key credentials from Algolia to the .env file.

With your internet browser, navigate through your Algolia dashboard to get the Application ID and Secret API Key credentials.

Click Settings at the bottom of the left-hand sidebar. This will navigate to the Settings page.

Next, click API Keys within the Access and Team section of the Settings page. You will be able to see the API keys associated with the account you have created. Algolia account.

Navigating to the API Keys page on Algolia Cloud
API Keys page on Algolia Cloud

In the API Keys page, take note of the App ID and Admin API Key value. These credentials will be used to authenticate the connection between the Laravel app and Algolia.

Viewing the Application ID and Admin API Keys from the Algolia API Keys page
Keys to the Application ID as well as API for Admin Keys

Incorporate the below code into your .env file by using your code editor and replace the placeholders with the corresponding Algolia API secrets.

ALGOLIA_APP_ID=APPLICATION_ID
 ALGOLIA_SECRET=ADMIN_API_KEY

Additionally, you can replace also the SCOUT_DRIVER variable using this code, which will change it from meilisearch to algolia. This change will tell Scout to utilize algolia instead. Algolia driver.

SCOUT_DRIVER=algolia

How Do I Create the Application Controllers

Within the app/Http/Controllers/ directory, create a TrainSearchController.php file to store a controller for the application. It will display and add data to it's Train Model.

Add the following code block into the TrainSearchController.php file to build the controller.

has('titlesearch'))
 $trains = Train::search($request->titlesearch)
 ->paginate(6);
 else
 $trains = Train::paginate(6);
 
 return view('Train-search',compact('trains'));
 
 
 /**
 * Get the index name for the model. *
 * @return string
 */
 public function create(Request $request)
 
 $this->validate($request,['title'=>'required']);
 
 $trains = Train::create($request->all());
 return back();
 
 

How to Create the Application Routes

In this stage, you'll create the routes for listing and adding trains into the database.

Navigate to the routes/web.php file and replace the current code with the block in the following.

 name ('trains-lists');
 
 Route::post('create-item', [TrainSearchController::class, 'create']) -> name ('create-item');

The code below creates two routes for the application. The GET request for the trains-lists route displays all the stored train information. A POST request of the /create-item route is used to create new train data.

How To Create the Application Views

Create a file within the resources/views/ directory and name it Train-search.blade.php. The file will display the user interface for the search function.

Add the content of the code block below into the Train-search.blade.php file to create a single page for the search functionality.

!DOCTYPE HTML> HTML> 
 Laravel - Laravel Scout Algolia Search Examples
 
 
"container">Laravel Full-Text search using Scout 
The Scout
Autocomplete="off"@if(count($errors))
 
 Whoops! There is an error when you input your information. 
 
 @foreach($errors->all() as $error)
  $error 
 @endforeach
 
 
 @endif
 
 
 
 
 
 
 
  $errors->first('title') 
 
 
 
 
 Create New Train
 
 
 
 
 
 
 Train Management
 
 
 
 
 
 
 
 
 
 
 
 Search
 
 
 
 
 
 
 @if($trains->count())
 @foreach($trains as $key => $item)
 
 @endforeach
 @else
 
 @endif
 
 
 Id
 Train Title
 Creation Date
 Updated Date
 
 
  ++$key 
  $item->title 
  $item->created_at 
  $item->updated_at 
 
 No train data available
 
 
  $trains->links() 
 
 
 
 
 

The HTML code above contains a form element with an input field as well as an option to type the name of a train, before saving it to a database. It also contains an HTML table which displays the id, title, created_at, as well as updated_at details of a train's entry in the database.

To view the page, navigate to http://127.0.0.1:8000/trains-lists from your web browser.

Viewing the Train model data displayed within the trains-lists page
Train model data

The database is not yet fully loaded, so you need to input the name of a demo train in the input field, then click Make New Train to save it.

Inserting a new train entry
Making a fresh train entry

To search to search, enter a key word from any of the train titles you have saved into the Input Title For Search input field and press Search.

As shown in the image below, only entries that contain the word "keyword" in their titles will display.

Using the search feature to find a train entry
Utilizing the search function to find a train entry

Meilisearch in conjunction with Laravel Scout

Developers can create and self-host an Meilisearch account inside their own cloud or on-premises infrastructure. Meilisearch also offers a test cloud offering like Algolia to developers that want to use the product without having to manage its infrastructure.

To integrate Meilisearch into Laravel, you must first install Meilisearch. Laravel application, execute the following command from the project's terminal.

composer require meilisearch/meilisearch-php

Next, you need to modify the Meilisearch variables within the .env file to make it more user-friendly.

Replacing those SCOUT_DRIVER, MEILISEARCH_HOST and MEILISEARCH_KEY variables of the .env file with the ones below.

SCOUT_DRIVER=meilisearch
 MEILISEARCH_HOST=http://127.0.0.1:7700
 MEILISEARCH_KEY=LockKey

The SCOUT_DRIVER key specifies which driver that Scout should use, while MEILISEARCH_HOST represents the domain where your Meilisearch instance is running. While not necessary during development, adding the MEILISEARCH_KEY in production is recommended.

NOTE: Comment out the Algolia ID and Secret when selecting Meilisearch as the preferred driver.

Once you have completed the .env configurations, you must index the pre-existing entries with the Artisan command in the following.

PHP artisan Scout: Import "App\Models\Train"

Laravel Scout is equipped with Database Engine

This engine makes use of "where-like" clauses, as well as full-text indexes to your current database to locate the most appropriate results for your search. You don't need to index your records to use the engine for database.

For the database engine to function, you must change your SCOUT_DRIVER .env variable to the database.

Start the .env file within the Laravel application and change the value of the SCOUT_DRIVER variable.

SCOUT_DRIVER = database

When you switch your driver to the database, Scout switches to using the database engine for full-text searches.

Collection Engine with Laravel Scout

Apart from Scout's database engine Scout also offers an collection engine. The engine makes use of "where" clauses as well as filtering for collection to find the most relevant search results.

Contrary to the database engine the collection engine works with the majority of relational databases Laravel is also able to support.

You can use the collection engine by setting the SCOUT_DRIVER environment variable to collection or by manually specifying the collection driver within the Scout configuration file.

SCOUT_DRIVER is collection

Explorer with Elasticsearch

Thanks to the strengths in Elasticsearch query, Explorer can be described as a contemporary Elasticsearch driver that works with Laravel Scout. It offers a compatible Scout driver, and offers benefits such as the ability to store, search, and analysing massive quantities of data in real-time. Elasticsearch with Laravel offers the results within milliseconds.

To use Elasticsearch Explorer, the Elasticsearch Explorer driver in your Laravel application, you'll need to set up your boilerplate docker-compose.yml file that the Laravel-Scout script created. You'll add the additional configurations for Elasticsearch and restart the containers.

Navigate to the docker-compose.yml file and change its contents using the next.

# For more information: https://laravel.com/docs/sail
 version: '3'
 services:
 laravel.test:
 build:
 context: ./vendor/laravel/sail/runtimes/8.1
 dockerfile: Dockerfile
 args:
 WWWGROUP: '$WWWGROUP'
 image: sail-8.1/app
 extra_hosts:
 - 'host.docker.internal:host-gateway'
 ports:
 - '$APP_PORT:-80:80'
 - '$VITE_PORT:-5173:$VITE_PORT:-5173'
 environment:
 WWWUSER: '$WWWUSER'
 LARAVEL_SAIL: 1
 XDEBUG_MODE: '$SAIL_XDEBUG_MODE:-off'
 XDEBUG_CONFIG: '$SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal'
 volumes:
 - '. :/var/www/html'
 networks:
 - sail
 depends_on:
 - mysql
 - redis
 - meilisearch
 - mailhog
 - selenium
 - pgsql
 - elasticsearch
 
 mysql:
 image: 'mysql/mysql-server:8.0'
 ports:
 - '$FORWARD_DB_PORT:-3306:3306'
 environment:
 MYSQL_ROOT_PASSWORD: '$DB_PASSWORD'
 MYSQL_ROOT_HOST: "%"
 MYSQL_DATABASE: '$DB_DATABASE'
 MYSQL_USER: '$DB_USERNAME'
 MYSQL_PASSWORD: '$DB_PASSWORD'
 MYSQL_ALLOW_EMPTY_PASSWORD: 1
 volumes:
 - 'sail-mysql:/var/lib/mysql'
 - './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
 networks:
 - sail
 healthcheck:
 test: ["CMD", "mysqladmin", "ping", "-p$DB_PASSWORD"]
 retries: 3
 timeout: 5s
 
 elasticsearch:
 image: 'elasticsearch:7.13.4'
 environment:
 - discovery.type=single-node
 ports:
 - '9200:9200'
 - '9300:9300'
 volumes:
 - 'sailelasticsearch:/usr/share/elasticsearch/data'
 networks:
 - sail
 kibana:
 image: 'kibana:7.13.4'
 environment:
 - elasticsearch.hosts=http://elasticsearch:9200
 ports:
 - '5601:5601'
 networks:
 - sail
 depends_on:
 - elasticsearch
 redis:
 image: 'redis:alpine'
 ports:
 - '$FORWARD_REDIS_PORT:-6379:6379'
 volumes:
 - 'sail-redis:/data'
 networks:
 - sail
 healthcheck:
 test: ["CMD", "redis-cli", "ping"]
 retries: 3
 timeout: 5s
 pgsql:
 image: 'postgres:13'
 ports:
 - '$FORWARD_DB_PORT:-5432:5432'
 environment:
 PGPASSWORD: '$DB_PASSWORD:-secret'
 POSTGRES_DB: '$DB_DATABASE'
 POSTGRES_USER: '$DB_USERNAME'
 POSTGRES_PASSWORD: '$DB_PASSWORD:-secret'
 volumes:
 - 'sailpgsql:/var/lib/postgresql/data'
 networks:
 - sail
 healthcheck:
 test: ["CMD", "pg_isready", "-q", "-d", "$DB_DATABASE", "-U", "$DB_USERNAME"]
 retries: 3
 timeout: 5s
 meilisearch:
 image: 'getmeili/meilisearch:latest'
 ports:
 - '$FORWARD_MEILISEARCH_PORT:-7700:7700'
 volumes:
 - 'sail-meilisearch:/meili_data'
 networks:
 - sail
 healthcheck:
 test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"]
 retries: 3
 timeout: 5s
 mailhog:
 image: 'mailhog/mailhog:latest'
 ports:
 - '$FORWARD_MAILHOG_PORT:-1025:1025'
 - '$FORWARD_MAILHOG_DASHBOARD_PORT:-8025:8025'
 networks:
 - sail
 selenium:
 image: 'selenium/standalone-chrome'
 extra_hosts:
 - 'host.docker.internal:host-gateway'
 volumes:
 - '/dev/shm:/dev/shm'
 networks:
 - sail
 networks:
 sail:
 driver: bridge
 volumes:
 sail-mysql:
 driver: local
 sail-redis:
 driver: local
 sail-meilisearch:
 driver: local
 sailpgsql:
 driver: local
 sailelasticsearch:
 driver: local

Then, you can run the command below to pull the latest Elasticsearch image you added to your docker-compose.yml file.

docker-composes up

Follow the Composer option below to integrate Explorer into the project.

composer require jeroen-g/explorer

You also need to create an administrator file for the Explorer driver.

Execute the Artisan command to create an explorer.config file for storage of the configurations.

php artisan vendor:publish --tag=explorer.config

The configuration file generated above is available under the directory /config directory.

Within your config/explorer.php file, it is possible to reference your model with your indexes key.

'indexes' => [
 \App\Models\Train::class
 ],

Modify the value of the SCOUT_DRIVER variable in the .env file to the value of elastic to set Scout to run the Explorer driver.

SCOUT_DRIVER = elastic

At this point, you'll use Explorer in the Train model using the Explorer interface and then overriding mappableAs() method.

Open the Train.php file within the App Models directory. Replace your existing code by the following code.

$this->Id,
 'title' => $this->title,
 ];
 
  

With the code you have put in above, you will be able to utilize Explorer to find text within the Train model.

Summary

To PHP designers, Laravel and add-ons like Scout make it a breeze to incorporate fast and robust full-text search features. By using Laravel's Database Engine, Collection Engine, and the capabilities provided by Meilisearch and Elasticsearch that allow you to connect with your database's data and implement advanced search mechanisms within milliseconds.

The ease of managing and updating your database ensures that your customers get the best possible experience and your code remains tidy and streamlined.

  • Simple setup and management on My dashboard. My dashboard
  • Support is available 24/7.
  • The top Google Cloud Platform hardware and network, powered by Kubernetes to ensure maximum capacity
  • A high-end Cloudflare integration for speed as well as security
  • The reach of the global audience is boosted by as many as 35 data centers, and more than 275 PoPs across the globe