Laravel Eloquent: How to Implement Full-Text Search

Updated: January 17, 2024 By: Guest Contributor Post a comment

Introduction

Full-text search is a sophisticated way for querying database content beyond simple pattern matching. When incorporating this with Laravel’s Eloquent, it leads to a powerful mechanism for searching through large amounts of textual data. In this tutorial, we will explore how to leverage Laravel’s Eloquent to perform full-text searches on your database to improve your application’s search feature.

Prerequisites

  • A basic understanding of Laravel
  • A Laravel application with a database that supports full-text indexes (like MySQL or PostgreSQL)
  • Some knowledge of Eloquent models and migrations

Setting Up the Environment

Before we start, ensure that you have a model and related migration. For this tutorial, we will use a Post model with a title and content field.

php artisan make:model Post -m

In the migration file, add:

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('content');
    $table->timestamps();
});

Basic Full-Text Search on a Single Column

Let’s start by searching a single column using MySQL’s MATCH() ... AGAINST() syntax:

Post::query()
    ->whereRaw(
        'MATCH (title) AGAINST (? IN BOOLEAN MODE)',
        [$searchTerm]
    )
    ->get();

While this example is straightforward, it only searches the title column. Let’s improve this to search multiple columns.

Full-Text Search Across Multiple Columns

To extend our search to cover both title and content, we can modify the MATCH() ... AGAINST() section in our query:

Post::query()
    ->whereRaw(
        'MATCH (title, content) AGAINST (? IN BOOLEAN MODE)',
        [$searchTerm]
    )
    ->get();

Advanced searching often requires modification of the database schema to add a full-text index. This can be done within the Laravel migration:

Schema::table('posts', function (Blueprint $table) {
    $table->fullText(['title', 'content']);
});

Using Laravel Scout

Laravel Scout is a full-text search package, abstracting the intricacies of searching models. After installation and driver configuration, using Scout becomes a breeze:

use Laravel\Scout\Searchable;
class Post extends Model
{
    use Searchable;
    public function toSearchableArray()
    {
        $array = $this->toArray();
        // Customize the data array...
        return $array;
    }
}

And here’s how to perform a search with Scout:

Post::search('$searchTerm')->get();

Eloquent: Advanced Full-Text Search Techniques

Laravel’s full-text search capabilities can be further enhanced by incorporating boolean mode and natural language search, relevance ranking, or using external search engines like Algolia:

Post::query()
    ->whereRaw(
        'MATCH (title, content) AGAINST (? IN NATURAL LANGUAGE MODE)',
        [$searchTerm]
    )
    ->orderBy('relevance', 'desc')
    ->get();

For applications needing even more functionality, packages such as TNTSearch or Elasticsearch integration might be suitable solutions.

Performance Considerations

Full-text searches can be resource-intensive. Caching results, optimizing indexes, and considering column types and lengths can significantly help with performance.

See also:

Conclusion

In this tutorial, we explored various ways to implement full-text search functionalities using Laravel Eloquent. Starting from a simple implementation to more advanced techniques, these methods enable developers to enhance the search experience within their applications effectively.