PHPackages                             sebastiansulinski/laravel-search - 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. [Search &amp; Filtering](/categories/search)
4. /
5. sebastiansulinski/laravel-search

ActiveProject[Search &amp; Filtering](/categories/search)

sebastiansulinski/laravel-search
================================

A lightweight search component for Laravel 11+.

v0.2.2(1y ago)593MITPHPPHP ^8.2

Since Nov 12Pushed 1y ago1 watchersCompare

[ Source](https://github.com/sebastiansulinski/laravel-search)[ Packagist](https://packagist.org/packages/sebastiansulinski/laravel-search)[ RSS](/packages/sebastiansulinski-laravel-search/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (5)Versions (15)Used By (0)

Lightweight search for Laravel 11 +
===================================

[](#lightweight-search-for-laravel-11-)

This package provides a simple, lightweight search component for Laravel 11+.

In contrast to the well known [Laravel Scout](https://laravel.com/docs/11.x/scout), it allows models to be associated with more than one index with separate payload for each, which was the much needed feature for my current project.

Currently only `typesense` driver is available, but if you feel like contributing a different implementation feel free to submit a PR.

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

[](#installation)

```
composer require sebastiansulinski/laravel-search
```

Configuration
-------------

[](#configuration)

Start by publishing vendor configuration file `search.php`

```
php artisan vendor:publish --provider="SebastianSulinski\Search\SearchServiceProvider"
```

Within the configuration file update parameters for your selected driver and add all models to the `models` array:

```
'models' => [
    App\Models\Book::class,
    App\Models\Movie::class,
]
```

You can also update the default queue the import job will run on using `SEARCH_QUEUE_CONNECTION` environment variable - otherwise the default queue will be used.

Typesense configuration
-----------------------

[](#typesense-configuration)

Add the following to your `services.php` config file and update accordingly:

```
'typesense' => [
    'api_key' => env('TYPESENSE_API_KEY', 'xyz'),
    'nodes' => [
        [
            'host' => env('TYPESENSE_HOST', 'localhost'),
            'port' => env('TYPESENSE_PORT', '8108'),
            'path' => env('TYPESENSE_PATH', ''),
            'protocol' => env('TYPESENSE_PROTOCOL', 'http'),
        ],
    ],
    'nearest_node' => [
        'host' => env('TYPESENSE_HOST', 'localhost'),
        'port' => env('TYPESENSE_PORT', '8108'),
        'path' => env('TYPESENSE_PATH', ''),
        'protocol' => env('TYPESENSE_PROTOCOL', 'http'),
    ],
    'connection_timeout_seconds' => env('TYPESENSE_CONNECTION_TIMEOUT_SECONDS', 2),
    'healthcheck_interval_seconds' => env('TYPESENSE_HEALTHCHECK_INTERVAL_SECONDS', 30),
    'num_retries' => env('TYPESENSE_NUM_RETRIES', 3),
    'retry_interval_seconds' => env('TYPESENSE_RETRY_INTERVAL_SECONDS', 1),
],
```

Initialisation
--------------

[](#initialisation)

To create collections ready for indexing, run the follow command from within the terminal:

```
php artisan app:initialise-search
```

You can set `SEARCH_REMOVE_UNDEFINED_COLLECTIONS` variable to `true` if you'd like to remove any previously created collections that are no longer present in the `search.php` config file while executing the above command.

Models
------

[](#models)

Each of the models defined within the configuration file under `models` array has to implement `IndexableDocument` and use `SearchIndexable` trait.

```
use Illuminate\Database\Eloquent\Model;
use SebastianSulinski\Search\IndexableDocument;
use SebastianSulinski\Search\SearchIndexable;

class Book extends Model implements IndexableDocument
{
    // ...
    use SearchIndexable;
```

You will also need to implement two methods:

### searchableAs

[](#searchableas)

This method returns a list of indexes the record should be listed under.

```
public static function searchableAs(): array
{
    return ['global_search'];
}
```

### toSearchableArray

[](#tosearchablearray)

This method returns the payload in the form of array with the key representing corresponding index.

```
public function toSearchableArray(): array
{
    return [
        'global_search' => [
            'type' => 'book',
            'id' => $this->getSearchKey(),
            'name' => $this->name,
            'author' => $this->author,
            'description' => $this->description,
            'created_at' => $this->created_at->timestamp,
        ],
    ];
}
```

You can also overwrite the `shouldBeSearchable` method to indicate whether the record should be indexed.

Register search request parameters for your given implementation
----------------------------------------------------------------

[](#register-search-request-parameters-for-your-given-implementation)

If you are using the built-in controller with the `SearchRequest`, within your `AppServiceProvider::boot` method add all relevant validation rules for a given index. These will be used with the `Indexer::search` method - if you are using different approach for the search, you can ignore these. By default, only `index` and `params` (as array) are validated - whatever you define via this method will be merged to it.

```
\SebastianSulinski\Search\Facades\Search::validation('global_search', fn (\Illuminate\Foundation\Http\FormRequest $request) => [
    'params.q' => [
        'nullable',
        'string',
    ],
    'params.query_by' => [
        'required',
        'string',
    ],
    'params.highlight_fields' => [
        'nullable',
        'string',
    ],
    'params.facet_by' => [
        'nullable',
        'string',
    ],
    'params.filter_by' => [
        'nullable',
        'string',
    ],
    'params.page' => [
        'nullable',
        'integer',
    ],
    'params.per_page' => [
        'nullable',
        'integer',
    ],
    'params.sort_by' => [
        'nullable',
        'string',
    ],
]);
```

Disable default routes
----------------------

[](#disable-default-routes)

To disable default routes add the following to your `AppServiceProvider::register` method:

```
\SebastianSulinski\Search\Facades\Search::withoutRoutes();
```

Import records
--------------

[](#import-records)

The following command will import all records for all indexes using default queue.

```
php artisan app:import-search
```

You can also specify the index you'd like to import:

```
php artisan app:import-search global_search
```

Remove index and all records
----------------------------

[](#remove-index-and-all-records)

To remove the index and all its records use the following command:

```
php artisan app:purge-search global_search
```

Contributions
-------------

[](#contributions)

Contributions are welcome, but please make sure your code contains all necessary bells and whistles - pint it etc.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance46

Moderate activity, may be stable

Popularity14

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

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 ~11 days

Recently: every ~33 days

Total

14

Last Release

405d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2211203?v=4)[Sebastian Sulinski](/maintainers/sebastiansulinski)[@sebastiansulinski](https://github.com/sebastiansulinski)

---

Top Contributors

[![sebastiansulinski](https://avatars.githubusercontent.com/u/2211203?v=4)](https://github.com/sebastiansulinski "sebastiansulinski (18 commits)")

---

Tags

searchlaravel

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/sebastiansulinski-laravel-search/health.svg)

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

###  Alternatives

[typesense/laravel-scout-typesense-driver

Laravel Scout Driver for Typesense

144637.2k3](/packages/typesense-laravel-scout-typesense-driver)[romangrinev/laravel-opensearch-engine

Custom Laravel Scout OpenSearch Engine

1319.8k](/packages/romangrinev-laravel-opensearch-engine)[omure/scout-advanced-meilisearch

Laravel Scout extension that allows to use meilisearch advanced features as well as has an extended collection driver for testing purposes.

123.9k](/packages/omure-scout-advanced-meilisearch)

PHPackages © 2026

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