Photo by Markus Winkler on Unsplash

How to implement search functionality in Laravel 8 using Laravel Scout and TNTSearch

I recently was working on a Laravel e-commerce project where I had to implement search functionality for users and products. Turning to the Laravel Documentation, I discovered Laravel Scout which according to the documentation, “provides a simple, driver based solution for adding full-text search to your Eloquent models”.

I know that many Laravel developers especially newbies may also face with the struggle of implementing a fast system for handling search especially one with an auto-complete or fuzzy feature.

Basically, Laravel Scout creates search indexes for each entry in a particular table which is used as a point of reference whenever you are searching that model.

TNTSearch on the other hand is a fully featured full text search engine written for PHP applications with a package build as a search driver for Laravel Scout.

In this tutorial I will show you how to implement search functionality using Laravel Scout and TNTSearch.

I assume that you already know how to set up your Laravel workspace and already know the basics of Laravel, so I will not go into that in this tutorial. If you do not, please take a look at this other tutorial

Install Laravel Scout using Composer Package Manager

composer require laravel/scout

Then install the Laravel TNTSearch package via composer

composer require teamtnt/laravel-scout-tntsearch-driver

Add the TNT service provider to your laravel’s config/app.php under the providers array.

'providers' => [
TeamTNT\Scout\TNTSearchScoutServiceProvider::class,
]

Next publish the Laravel scout configuration file with the following code

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

This will create a scout.php file in your Laravel config folder.

Next, on your .env file add the following

SCOUT_DRIVER=tntsearch
TNTSEARCH_FUZZINESS=true

Finally, in your new config/scout.php add the following code

'tntsearch' => [
'storage' => storage_path(),
'fuzziness' => env('TNTSEARCH_FUZZINESS', false),
'fuzzy' => [
'prefix_length' => 2,
'max_expansions' => 50,
'distance' => 2
],
'asYouType' => true,
'steemer' => \TeamTNT\TNTSearch\Steemer\NoSteemer::class,
'tokenizer' => \TeamTNT\TNTSearch\Support\ProductTokenizer::class,
'searchBoolean' => env('TNTSEARCH_BOOLEAN', false),
'maxDocs' => env('TNTSEARCH_MAX_DOCS', 500),
],

The next step is to implement the search functionality in the app.

The first step is to add Laravel\Scout\Searchable trait to the model you want to implement search on. It should look like this:

<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Post extends Model{
use Searchable;
}

Next, add the following properties to your on your model class.

public $asYouType = true;public function toSearchableArray(){
$array = [
'id' => $this->id,
'username' => $this->username
];
return $array;
}

The toSearchableArray method in the code above contains a key value pair of the columns you want Laravel to add to the search index. If you do not specify those values, Laravel may add every column to the index and you might end up with the wrong search results.

Example, if you are searching through the username column on your model did not parse the toSearchableArray method, Laravel may go on to index other columns in your model and return search results that closely match those columns.

Note: Always make sure you add the primary key column to your searchable array else your search results will not return any values

With these you are ready to implement your search functionality, and Laravel makes it really easy.

<?phpnamespace App\Http\Controllers;use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller{

function searchPost(Request $request){
$search_results = Post::search($request->keyword)->get();
}
}

This will return an eloquent collection of all the items that match the search keyword and you can now procced as you would like by either passing the values to a view or returning a JSON response for APIs.

You can checkout a working example on my Github repository https://github.com/UtyEmma/laravel-tntsearch.git

Was this tutorial helpful? I would love to here from you in the comments.

I am a full stack web developer with interest in learning better approaches and writing about them.