Laravel 10 Scout Full Text Search with Algolia Tutorial

Last Updated on by in Laravel

Laravel scout full-text search tutorial; In a web application, a Full-text search feature is exorbitantly helpful for site users to traverse through content-rich web and mobile applications.

This comprehensive tutorial will explain how to profoundly integrate full-text search in a Laravel application using the Laravel Scout algolia library.

We will gradually raise the curtain from every step that is essential to share on creating a full-text search using laravel scout algolia;

Adding or implementing Algolia in Laravel has become super easy, and that has been made possible by Laravel Scout. Laravel scout offers a powerful scout package that amplifies the integration of full-text search directly through your model.

Laravel Scout renders a simple, driver-based solution for implementing a full-text search to your Eloquent models. Utilizing model observers, Scout automatically retains your search indexes in sync with your Eloquent records.

Scout comes with Algolia and MeiliSearch drivers; nevertheless, writing custom drivers has never been easy, not just that you can freely extend Scout with your custom search implementations.

Laravel 10 Algolia Full Text Search Example

  • Step 1: Create New Laravel Project
  • Step 2: Update Database Details in ENV
  • Step 3: Install Laravel Scout & Algolia Packages
  • Step 4: Set Up Algolia in Laravel
  • Step 5: Set Up Model and Migration
  • Step 6: Set Up Controller
  • Step 7: Create Routes
  • Step 8: Configure Blade View
  • Step 9: Run Laravel Project

Create New Laravel Project

First up, open console, type the below command and rightly, after executing the command to install the new laravel app, ignore the below command if the app is already created.

composer create-project --prefer-dist laravel/laravel laravel-demo

After the app is created, get into the app’s folder:

cd laravel-demo

Update Database Details in ENV

Next, you have to place the database name, username, and password into the .env configuration file.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password

If you are using MAMP local server in macOs; make sure to append UNIX_SOCKET and DB_SOCKET below database credentials in .env file.

UNIX_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock
DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock

Install Laravel Scout & Algolia Packages

Now, we need to install the laravel scout and algolia search dependencies using the composer tool; these packages are imperative in order to implement instant search work in laravel.

Let us execute the command to install the scout package in laravel.

composer require laravel/scout

We have added the scout library in laravel; let inform the laravel as well about the existence of the scout package; you should publish the Scout configuration file using the vendor:publish Artisan command.

The execution of the following command will publish the scout.php configuration file to your application’s config directory:

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

Next, update the following line of code into the .env file.

SCOUT_QUEUE=true

Further, we need to add the algolia search client package in laravel, so execute the following command.

composer require algolia/algoliasearch-client-php

Set Up Algolia in Laravel

In this section, we need to head over to the Algolia website and create an account to get the API keys.

Algolia offers AI-powered search & discovery across websites & apps, not just that it gives top-notch UX for web, as well as ecommerce apps.

Set Up Algolia in Laravel

You have to navigate to the API Keys segment; within the API Keys page, look under the Your API Keys section. From there, copy the Application ID and Admin API keys and define them into the .env configuration file.

ALGOLIA_APP_ID=add_application_id
ALGOLIA_SECRET=add_admin_api_key

Set Up Model and Migration

This step explains how to generate a Model similarly setting up model and run migration to add a new table into the database. Let us generate the new Product model file using the below command.

php artisan make:model Product -m

Next, you need to app/Models/Product.php file and update the Product table values which will be added to database. Ideally, we also need to import the scout Searchable service, and define the searchableAs() method.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Product extends Model
{
    use HasFactory;
    use Searchable;

    public $fillable = ['product_name'];


    /**
     * Get the index name for the model.
    */
    public function searchableAs()
    {
        return 'product_index';
    }    
}

Thereafter, you need to open database/migrations/create_products_table.php file and add the following code inside the file.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('product_name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Now, you have to run the following command to run the migration.

php artisan migrate

Set Up Controller

This section of the tutorial tells you to generate a new controller, where we will place the code to display the search component in view and create the full-text search function.

php artisan make:controller TextSearchController

The new controller has been generated, now head over to app\Http\Controllers\TextSearchController.php and add the following code.

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Models\Product;

class TextSearchController extends Controller
{

    public function index(Request $request)
    {
        if($request->has('product_search')){
            $products = Product::search($request->product_search)
                ->paginate(7);
        }else{
            $products = Product::paginate(7);
        }
        return view('welcome', compact('products'));
    }

    public function fullTextSearch(Request $request)
    {
        $this->validate($request,['product_name'=>'required']);

        $products = Product::create($request->all());
        return back();
    }
}

Create Routes

In this section, we need to open the routes/web.php file and define two routes that will concurrently handle text search in laravel.

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TextSearchController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/products', [TextSearchController::class, 'index'])->name('products');

Route::post('/create-product', [TextSearchController::class, 'fullTextSearch'])->name('createProduct');

Configure Blade View

In the last section of this profound tutorial, we need to create the blade view hence open the default welcome.blade.php file and add the following code.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel Algolia Scout Full Text Search Example</title>

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet">

</head>

<body>
    <div class="container mt-5" style="max-width: 800px">
        <form method="POST" action="{{ route('createProduct') }}" autocomplete="off">
            @if(count($errors))
            <div class="alert alert-danger">
                <strong>Whoops!</strong> Error occured
                <br />
                <ul>
                    @foreach($errors->all() as $error)
                    <li>{{ $error }}</li>
                    @endforeach
                </ul>
            </div>
            @endif


            <input type="hidden" name="_token" value="{{ csrf_token() }}">

            <div class="row">
                <div class="col-md-6">
                    <div class="form-group {{ $errors->has('product_name') ? 'has-error' : '' }}">
                        <input type="text" id="product_name" name="product_name" class="form-control"
                            placeholder="Enter Name" value="{{ old('product_name') }}">
                        <span class="text-danger">{{ $errors->first('product_name') }}</span>
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="form-group">
                        <button class="btn btn-outline-danger">Add Product</button>
                    </div>
                </div>
            </div>
        </form>

        <div class="panel panel-primary mt-4">
            <div class="panel-heading mb-2"><strong>Maange products:</strong></div>
            <div class="panel-body">
                <form method="GET" action="{{ route('products') }}">


                    <div class="row mb-5">
                        <div class="col-md-6">
                            <div class="form-group">
                                <input type="text" name="product_search" class="form-control"
                                    placeholder="Search by name" value="{{ old('product_search') }}">
                            </div>
                        </div>
                        <div class="col-md-6">
                            <div class="form-group">
                                <button class="btn btn-success">Search</button>
                            </div>
                        </div>
                    </div>
                </form>

                <table class="table text-center">
                    <thead>
                        <th>#Id</th>
                        <th>Name</th>
                        <th>Create Date</th>
                        <th>Updated Date</th>
                    </thead>
                    <tbody>
                        @if($products->count())
                        @foreach($products as $key => $product)
                        <tr>
                            <td>{{ ++$key }}</td>
                            <td>{{ $product->product_name }}</td>
                            <td>{{ $product->created_at }}</td>
                            <td>{{ $product->updated_at }}</td>
                        </tr>
                        @endforeach
                        @else
                        <tr>
                            <td colspan="4">There are no data.</td>
                        </tr>
                        @endif
                    </tbody>
                </table>
                {{ $products->links() }}
            </div>
        </div>


    </div>
</body>

</html>

Run Laravel Project

The following command invokes the laravel development server; let us run the command to run the app.

php artisan serve

You may use the below url to view the app.

http://127.0.0.1:8000/products

Laravel Algolia full text search

Conclusion

The Laravel Algolia full text search tutorial is just completed; we have seen the basic functioning and integration of full-text search.

However, laravel scout offers tons of other features which can make your search more powerful and unbound user-friendly. We hope this step by step guide will help you understand the concept of full-text search.