Why Use PostgreSQL for Full-Text Search in Laravel
When building apps with searchable content—blogs, marketplaces, knowledge bases—search is no longer optional. While Laravel supports packages like Scout and Algolia, PostgreSQL’s built-in full-text search offers a powerful, self-contained solution without third-party APIs.
PostgreSQL supports advanced text indexing using tsvector
and tsquery
, ideal for Laravel applications that need performant, scalable search.
PostgreSQL gives you deep, native search without leaving your database. Laravel makes it approachable.
Key Takeaways
- Enable powerful, native search without third-party services
- Use
tsvector
columns and GIN indexes for optimized queries - Integrate with Laravel using Eloquent or raw queries
- Works great with multilingual content
Setting Up PostgreSQL Full-Text Search in Laravel
Configure PostgreSQL in Laravel
Ensure your .env
file is using PostgreSQL:
DB_CONNECTION=pgsql
Update .env
and run:
php artisan migrate
Create a Model and Migration
Example: Let’s say you’re building a searchable posts
table.
php artisan make:model Post -m
Migration example with tsvector
:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->tsvector('search_vector')->nullable();
$table->timestamps();
});
To support tsvector
, create a macro in a migration stub or use a custom SQL query in your migration.
Generate the Search Vector Automatically
Use a database trigger:
CREATE FUNCTION posts_search_vector() RETURNS trigger AS $$
BEGIN
NEW.search_vector :=
setweight(to_tsvector('english', coalesce(NEW.title, '')), 'A') ||
setweight(to_tsvector('english', coalesce(NEW.body, '')), 'B');
RETURN NEW;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
ON posts FOR EACH ROW EXECUTE PROCEDURE posts_search_vector();
Add a GIN Index
CREATE INDEX posts_search_vector_index
ON posts USING GIN (search_vector);
Performing a Full-Text Search Query in Laravel
You can use Eloquent or raw queries.
Using Raw SQL
$results = DB::table('posts')
->whereRaw("search_vector @@ plainto_tsquery('english', ?)", [$search])
->get();
Using a Scope in Eloquent
// Post.php
public function scopeSearch($query, $term)
{
return $query->whereRaw(
"search_vector @@ plainto_tsquery('english', ?)",
[$term]
);
}
// Usage:
Post::search('laravel')->get();
Blade Example: Search View
<form method="GET" action="{{ route('posts.index') }}">
<input type="text" name="search" placeholder="Search posts...">
<button type="submit">Search</button>
</form>
@if(request('search'))
<p>Searching for: <strong>{{ request('search') }}</strong></p>
@endif
@foreach($posts as $post)
<div>
<h2>{{ $post->title }}</h2>
<p>{{ Str::limit($post->body, 150) }}</p>
</div>
@endforeach
Advanced Tips
Language Configuration
PostgreSQL supports many languages:
SELECT to_tsvector('french', 'bonjour tout le monde');
Match your application’s locale.
Weighting and Ranking
Use ts_rank
to order results:
$posts = DB::table('posts')
->select('*', DB::raw("ts_rank(search_vector, plainto_tsquery('english', ?)) as rank"))
->whereRaw("search_vector @@ plainto_tsquery('english', ?)", [$term, $term])
->orderByDesc('rank')
->get();
Full-Text Search vs Laravel Scout
Feature | PostgreSQL Full-Text | Laravel Scout + Algolia |
---|---|---|
Cost | Free | Subscription required |
Setup | DB triggers and indexes | API + indexing config |
Speed | Fast for mid-scale apps | Super fast |
Customization | High (weights, language) | Low-medium |
Offline support | ✅ Yes | ❌ No |
Use PostgreSQL when:
- You need built-in search for internal tools, dashboards, or apps with rich text
- You want full control over indexing
Use Laravel Scout when:
- You want fuzzy matching, typo correction, and external APIs
FAQ
Is PostgreSQL full-text search fast? Yes, especially when combined with GIN indexes.
Does Laravel support tsvector out of the box? Not directly, but it integrates well through raw queries or scopes.
Can I use Scout and PostgreSQL together? Yes, but it’s typically one or the other based on your use case.
What if I need multilingual search? PostgreSQL supports multiple language configurations in to_tsvector()
and tsquery()
.
Helpful Resources
Conclusion
PostgreSQL full-text search is an underused but powerful feature in Laravel applications. With minimal setup—just a migration, a trigger, and a few lines of SQL—you can turn any table into a search powerhouse.
Whether you’re building a blog, marketplace, or dashboard, full-text search in PostgreSQL is fast, reliable, and fully native to your app. If you’re already using PostgreSQL with Laravel, you’re only a few steps away from excellent search.