PHPackages                             seongbae/laravel-searchable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. seongbae/laravel-searchable

ActiveLibrary

seongbae/laravel-searchable
===========================

Pragmatically search through models and other sources

1.13(2mo ago)095MITPHPPHP ^8.2|^8.3|^8.4CI failing

Since Dec 7Pushed 2mo agoCompare

[ Source](https://github.com/seongbae/laravel-searchable)[ Packagist](https://packagist.org/packages/seongbae/laravel-searchable)[ Docs](https://github.com/spatie/laravel-searchable)[ Fund](https://spatie.be/open-source/support-us)[ RSS](/packages/seongbae-laravel-searchable/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (8)Dependencies (8)Versions (25)Used By (0)

[![](https://camo.githubusercontent.com/2bedf63f24cda7efab02da955dc11fb7ef8a060e2f26b73c33a7aac84529b8a3/68747470733a2f2f6769746875622d6164732e73332e65752d63656e7472616c2d312e616d617a6f6e6177732e636f6d2f737570706f72742d756b7261696e652e7376673f743d31)](https://supportukrainenow.org)

Laravel Searchable
==================

[](#laravel-searchable)

[![Latest Version on Packagist](https://camo.githubusercontent.com/50a957fab28366b21e5087ea0b78d9091a3b67cc0c6e77faf9c4783ed54bcc3d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7370617469652f6c61726176656c2d73656172636861626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spatie/laravel-searchable)[![Test Status](https://camo.githubusercontent.com/dd43e7b42fc917ffbd0ff55de1561ea4860725d643ed892a09f36f04a968f21a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f7370617469652f6c61726176656c2d73656172636861626c652f72756e2d74657374733f6c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/dd43e7b42fc917ffbd0ff55de1561ea4860725d643ed892a09f36f04a968f21a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f7370617469652f6c61726176656c2d73656172636861626c652f72756e2d74657374733f6c6162656c3d7465737473267374796c653d666c61742d737175617265)[![Code Style Status](https://camo.githubusercontent.com/4bc6d5174c0b4b78af77906f70bcedf265532caddb9289f2b642083134145529/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f7370617469652f6c61726176656c2d73656172636861626c652f436865636b253230262532306669782532307374796c696e673f6c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/4bc6d5174c0b4b78af77906f70bcedf265532caddb9289f2b642083134145529/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f7370617469652f6c61726176656c2d73656172636861626c652f436865636b253230262532306669782532307374796c696e673f6c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)[![Total Downloads](https://camo.githubusercontent.com/bd36d142aa10630b99f2ab8e690f6d7fd604f08cf2907f714a45d185a41a72be/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7370617469652f6c61726176656c2d73656172636861626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spatie/laravel-searchable)

This package makes it easy to get structured search from a variety of sources. Here's an example where we search through some models. We already did some small preparation on the models themselves.

```
$searchResults = (new Search())
   ->registerModel(User::class, 'name')
   ->registerModel(BlogPost::class, 'title')
   ->search('john');
```

The search will be performed case insensitive. `$searchResults` now contains all `User` models that contain `john` in the `name` attribute and `BlogPost`s that contain 'john' in the `title` attribute.

In your view you can now loop over the search results:

```
Search

There are {{ $searchResults->count() }} results.

@foreach($searchResults->groupByType() as $type => $modelSearchResults)
   {{ $type }}

   @foreach($modelSearchResults as $searchResult)

            {{ $searchResult->title }}

   @endforeach
@endforeach
```

In this example we used models, but you can easily add a search aspect for an external API, list of files or an array of values.

Support us
----------

[](#support-us)

[![](https://camo.githubusercontent.com/a5fef0345e0786c2b75ca185dfeba2287873caa4655750b136d567fa998845fd/68747470733a2f2f6769746875622d6164732e73332e65752d63656e7472616c2d312e616d617a6f6e6177732e636f6d2f6c61726176656c2d73656172636861626c652e6a70673f743d31)](https://spatie.be/github-ad-click/laravel-searchable)

We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require spatie/laravel-searchable
```

Usage
-----

[](#usage)

### Preparing your models

[](#preparing-your-models)

In order to search through models you'll have to let them implement the `Searchable` interface.

```
namespace Spatie\Searchable;

interface Searchable
{
    public function getSearchResult(): SearchResult;
}
```

You'll only need to add a `getSearchResult` method to each searchable model that must return an instance of `SearchResult`. Here's how it could look like for a blog post model.

```
use Spatie\Searchable\Searchable;
use Spatie\Searchable\SearchResult;

class BlogPost extends Model implements Searchable
{
     public function getSearchResult(): SearchResult
     {
        $url = route('blogPost.show', $this->slug);

         return new \Spatie\Searchable\SearchResult(
            $this,
            $this->title,
            $url
         );
     }
}
```

### Searching models

[](#searching-models)

With the models prepared you can search them like this:

```
$searchResults = (new Search())
   ->registerModel(User::class, 'name')
   ->search('john');
```

The search will be performed case insensitive. `$searchResults` now contains all `User` models that contain `john` in the `name` attribute.

You can also pass multiple attributes to search through:

```
// use multiple model attributes

$searchResults = (new Search())
   ->registerModel(User::class, 'first_name', 'last_name')
   ->search('john');

// or use an array of model attributes

$searchResults = (new Search())
   ->registerModel(User::class, ['first_name', 'last_name'])
   ->search('john');
```

To get fine grained control you can also use a callable. This way you can also search for exact matches, apply scopes, eager load relationships, or even filter your query like you would using the query builder.

```
$search = (new Search())
   ->registerModel(User::class, function(ModelSearchAspect $modelSearchAspect) {
       $modelSearchAspect
          ->addSearchableAttribute('name') // return results for partial matches on usernames
          ->addExactSearchableAttribute('email') // only return results that exactly match the e-mail address
          ->active()
          ->has('posts')
          ->with('roles');
});
```

### Creating custom search aspects

[](#creating-custom-search-aspects)

You are not limited to only registering basic models as search aspects. You can easily create your own, custom search aspects by extending the `SearchAspect` class.

Consider the following custom search aspect to search an external API:

```
class OrderSearchAspect extends SearchAspect
{
    public function getResults(string $term): Collection
    {
        return OrderApi::searchOrders($term);
    }
}
```

This is how you can use it:

```
$searchResults = (new Search())
   ->registerAspect(OrderSearchAspect::class)
   ->search('john');
```

### Limiting aspect results

[](#limiting-aspect-results)

It is possible to limit the amount of results returned by each aspect by calling `limitAspectResults` prior to performing the search.

```
$searchResults = (new Search())
    ->registerAspect(BlogPostAspect::class)
    ->limitAspectResults(50)
    ->search('How To');
```

### Rendering search results

[](#rendering-search-results)

Here's an example on rendering search results:

```
Search

There are {{ $searchResults->count() }} results.

@foreach($searchResults->groupByType() as $type => $modelSearchResults)
   {{ $type }}

   @foreach($modelSearchResults as $searchResult)

            {{ $searchResult->title }}

   @endforeach
@endforeach
```

You can customize the `$type` by adding a public property `$searchableType` on your model or custom search aspect

```
class BlogPost extends Model implements Searchable
{
    public $searchableType = 'custom named aspect';
}
```

### Testing

[](#testing)

```
composer test
```

### Changelog

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.

### Security

[](#security)

If you've found a bug regarding security please mail  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Alex Vanderbist](https://github.com/AlexVanderbist)
- [Freek Van der Herten](https://github.com/freekmurze)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

54

—

FairBetter than 97% of packages

Maintenance87

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity88

Battle-tested with a long release history

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~115 days

Recently: every ~480 days

Total

24

Last Release

65d ago

Major Versions

0.0.3 → 1.0.02018-12-27

PHP version history (4 changes)0.0.1PHP ^7.1

1.3.0PHP ^7.2

1.11.2PHP ^7.3|^8.0

1.13PHP ^8.2|^8.3|^8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/634527ef489f1765aec336951fc1103ce1347eecff9e39c9ee4b8450cb217a43?d=identicon)[seongbae](/maintainers/seongbae)

---

Top Contributors

[![freekmurze](https://avatars.githubusercontent.com/u/483853?v=4)](https://github.com/freekmurze "freekmurze (84 commits)")[![AlexVanderbist](https://avatars.githubusercontent.com/u/6287961?v=4)](https://github.com/AlexVanderbist "AlexVanderbist (38 commits)")[![seongbae](https://avatars.githubusercontent.com/u/1762739?v=4)](https://github.com/seongbae "seongbae (9 commits)")[![AdrianMrn](https://avatars.githubusercontent.com/u/12762044?v=4)](https://github.com/AdrianMrn "AdrianMrn (8 commits)")[![jadsalhani](https://avatars.githubusercontent.com/u/6623311?v=4)](https://github.com/jadsalhani "jadsalhani (8 commits)")[![riasvdv](https://avatars.githubusercontent.com/u/3626559?v=4)](https://github.com/riasvdv "riasvdv (7 commits)")[![netpok](https://avatars.githubusercontent.com/u/6945600?v=4)](https://github.com/netpok "netpok (6 commits)")[![WalrusSoup](https://avatars.githubusercontent.com/u/5719851?v=4)](https://github.com/WalrusSoup "WalrusSoup (4 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (4 commits)")[![larsjanssen6](https://avatars.githubusercontent.com/u/7254997?v=4)](https://github.com/larsjanssen6 "larsjanssen6 (4 commits)")[![JamesFreeman](https://avatars.githubusercontent.com/u/916500?v=4)](https://github.com/JamesFreeman "JamesFreeman (3 commits)")[![SamuelNitsche](https://avatars.githubusercontent.com/u/24483576?v=4)](https://github.com/SamuelNitsche "SamuelNitsche (2 commits)")[![mojtabaahn](https://avatars.githubusercontent.com/u/9845317?v=4)](https://github.com/mojtabaahn "mojtabaahn (2 commits)")[![voydz](https://avatars.githubusercontent.com/u/373533?v=4)](https://github.com/voydz "voydz (2 commits)")[![PovilasKorop](https://avatars.githubusercontent.com/u/1510147?v=4)](https://github.com/PovilasKorop "PovilasKorop (1 commits)")[![amaelftah](https://avatars.githubusercontent.com/u/17250137?v=4)](https://github.com/amaelftah "amaelftah (1 commits)")[![grantholle](https://avatars.githubusercontent.com/u/1189456?v=4)](https://github.com/grantholle "grantholle (1 commits)")[![shuvroroy](https://avatars.githubusercontent.com/u/21066418?v=4)](https://github.com/shuvroroy "shuvroroy (1 commits)")[![SocolaDaiCa](https://avatars.githubusercontent.com/u/18243451?v=4)](https://github.com/SocolaDaiCa "SocolaDaiCa (1 commits)")[![timacdonald](https://avatars.githubusercontent.com/u/24803032?v=4)](https://github.com/timacdonald "timacdonald (1 commits)")

---

Tags

spatielaravel-searchable

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/seongbae-laravel-searchable/health.svg)

```
[![Health](https://phpackages.com/badges/seongbae-laravel-searchable/health.svg)](https://phpackages.com/packages/seongbae-laravel-searchable)
```

###  Alternatives

[spatie/laravel-searchable

Pragmatically search through models and other sources

1.4k1.5M23](/packages/spatie-laravel-searchable)[spatie/laravel-analytics

A Laravel package to retrieve Google Analytics data.

3.2k5.7M57](/packages/spatie-laravel-analytics)[spatie/laravel-tags

Add tags and taggable behaviour to your Laravel app

1.7k10.3M86](/packages/spatie-laravel-tags)[spatie/laravel-failed-job-monitor

Get notified when a queued job fails

1.0k2.6M4](/packages/spatie-laravel-failed-job-monitor)[spatie/laravel-image-optimizer

Optimize images in your Laravel app

1.3k6.5M43](/packages/spatie-laravel-image-optimizer)[spatie/laravel-queueable-action

Queueable action support in Laravel

6993.3M15](/packages/spatie-laravel-queueable-action)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
