PHPackages                             shureban/laravel-searcher - 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. shureban/laravel-searcher

ActiveLaravel-package[Search &amp; Filtering](/categories/search)

shureban/laravel-searcher
=========================

Laravel SDK for searching data in DB using requests

2.4.1(2y ago)24.9k↓100%MITPHPPHP ^8.1

Since Nov 9Pushed 2y ago1 watchersCompare

[ Source](https://github.com/Shureban/laravel-searcher)[ Packagist](https://packagist.org/packages/shureban/laravel-searcher)[ RSS](/packages/shureban-laravel-searcher/feed)WikiDiscussions master Synced today

READMEChangelog (10)DependenciesVersions (10)Used By (0)

Laravel query searcher
======================

[](#laravel-query-searcher)

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

[](#installation)

Require this package with composer using the following command:

```
composer require shureban/laravel-searcher
```

Add the following class to the `providers` array in `config/app.php`:

```
Shureban\LaravelSearcher\SearcherServiceProvider::class,
```

You can also publish the config file to change implementations (i.e. interface to specific class).

```
php artisan vendor:publish --provider="Shureban\LaravelSearcher\SearcherServiceProvider"
```

How to use
----------

[](#how-to-use)

By default, place your searchers in app\\Http\\Searchers folder.

### Example with all searcher variations.

[](#example-with-all-searcher-variations)

#### getQuery method

[](#getquery-method)

Should return query for applying filters. You may modify that query `Model::query()->with(['relation_1', 'relation_2' => fn() => ...])`

#### getFilters method

[](#getfilters-method)

Should return associative array where:

- keys must be equal to your request params
- values must be objects related of `\Shureban\LaravelSearcher\Searcher`

#### Example

[](#example)

In that case:

- 'age' - is request parameter age
- 'client\_age' - is DB column name
- new Between(...) - filter rule

```
return ['age' => new Between('client_age')];
```

```
class YourFirstSearcher extends Searcher
{
    /**
     * @return Builder
     */
    protected function getQuery(): Builder
    {
        return Model::query();
    }

    /**
     * @return ColumnFilter[]
     */
    protected function getFilters(): array
    {
        return [
          //| Request param name | Filter object               | Expected value type
          //-------------------------------------------------------------------------
            // Simple cases
            'is_single'        => new Boolean('is_single'),     // bool
            'age'              => new Between('client_age'),    // array (2 elements)
            'salary'           => new BetweenRange('salary'),   // array (2 elements)
            'birthday'         => new BetweenDates('birthday'), // array (2 elements)
            'id'               => new Equal('id'),              // any
            'created_at'       => new EqualDate('created_at'),  // date
            'height'           => new Gt('height'),             // number
            'max_height'       => new Gte('max_height'),        // number
            'updated_at'       => new GtDate('updated_at'),     // date
            'deleted_at'       => new GteDate('deleted_at'),    // date
            'statuses'         => new In('status'),             // array
            'image_id'         => new IsNull('image_id'),       // bool
            'email'            => new Like('email'),            // mixed
            'foot_size'        => new Lt('foot_size'),          // number
            'max_foot_size'    => new Lte('max_foot_size'),     // number
            'birthday'         => new LtDate('birthday'),       // date
            'hired_at'         => new LteDate('hired_at'),      // date
            'partner_statuses' => new NotIn('partner_status'),  // array
            'only_every_even'  => new Callback(
                fn(Builder $query, mixed $value) => $query->whereRaw('(id % 2 = 0)')
            ),                                                  // mixed

            // Modifier used. That case means, all rows where manager_id is equal to same value or null
            'manager_id' => new OrNull(new Like('manager_id')),
            'full_name'  => new OrEmpty(new Like('full_name')),
            'owner_id'   => new MultipleOr(new Equal('user_id'), new Like('manager_id'), new Relation('brokers', new Equal('id'))),
            // Working with relation modifiers
            'invoice_payouts'          => new Relation('invoices', new Between('amount')),
            'invoice_statuses'         => new Relation('invoices', new In('status')),
            'invoice_payment_method'   => new Relation('invoices', new Like('payment_method')),
            'invoice_process_statuses' => new Relation('invoices', new NotIn('process_status')),
        ];
    }
}
```

### How to change Sorting

[](#how-to-change-sorting)

For change default sort column, you should override method `sortColumn`.

```
protected function sortColumn(): ?string
{
    return $this->request->get('sort_column', 'created_at');
}
```

If you need to change order behavior related with some column, do this. Override method `applySortBy`

```
protected function applySortBy(Builder $query, string $sortColumn, SortType $sortType): Builder
{
    return match ($sortColumn) {
        'your_special_column'   => $query->orderBy('column_1', $sortType)->orderBy('column_2', $sortType),
        default                 => parent::applySortBy($query, $sortColumn, $sortType),
    };
}
```

Real case
---------

[](#real-case)

### Your first searcher

[](#your-first-searcher)

```
namespace App\Http\Searchers;

use Illuminate\Database\Eloquent\Builder;
use Shureban\LaravelSearcher\Filters\Like;
use Shureban\LaravelSearcher\Searcher;

class YourFirstSearcher extends Searcher
{
    /**
     * @return Builder
     */
    protected function getQuery(): Builder
    {
        return Model::query();
    }

    /**
     * @return ColumnFilter[]
     */
    protected function getFilters(): array
    {
        return [
            'id' => new Like('id'),
        ];
    }
}
```

### Request

[](#request)

```
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Enum;
use Illuminate\Validation\Rules\In;
use Shureban\LaravelSearcher\Enums\SortType;

class YourRequest extends FormRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            'id'            => ['int', 'min:1', 'max:2000000000'],
            'sort_column'   => [new In(['id'])],
            'sort_type'     => [new Enum(SortType::class)],
        ];
    }
}
```

### Controller

[](#controller)

```
namespace App\Http\Controllers;

use Illuminate\Routing\Controller as BaseController;
use App\Http\Requests\YourFirstSearcher;

class YourController extends BaseController
{
    /**
     * @param YourRequest $request
     *
     * @return JsonResponse
     */
    public function __invoke(YourRequest $request): JsonResponse
    {
        $searcher  = new YourFirstSearcher($request);
        // Collection with all models without pagination and slicing by per_page
        $allModels = $searcher->all();
        // Collection contains per_page number of models and with page offset
        $models    = $searcher->get();
        // Base Laravel LengthAwarePaginator
        $paginator = $searcher->paginate();

        return new JsonResponse($paginator);
    }
}
```

###  Health Score

32

—

LowBetter than 74% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity25

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity60

Established project with proven stability

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

Recently: every ~83 days

Total

9

Last Release

864d ago

Major Versions

1.1.1 → 2.0.02022-12-10

PHP version history (2 changes)1.0.0PHP ^8.0

1.1.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/d6df85acf6d2ae745da6af44e0db9c97e64c528ef5b9b0276bad5c4ac7f3888a?d=identicon)[Shureban](/maintainers/Shureban)

---

Top Contributors

[![Shureban](https://avatars.githubusercontent.com/u/5560764?v=4)](https://github.com/Shureban "Shureban (34 commits)")

---

Tags

searchmodelsrequestsSearchershureban

### Embed Badge

![Health badge](/badges/shureban-laravel-searcher/health.svg)

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

###  Alternatives

[elasticsearch/elasticsearch

PHP Client for Elasticsearch

5.5k175.3M849](/packages/elasticsearch-elasticsearch)[ruflin/elastica

Elasticsearch Client

2.3k49.8M189](/packages/ruflin-elastica)[solarium/solarium

PHP Solr client

93532.1M89](/packages/solarium-solarium)[titasgailius/search-relations

A Laravel Nova tool.

3607.1M4](/packages/titasgailius-search-relations)[opensearch-project/opensearch-php

PHP Client for OpenSearch

14823.0M45](/packages/opensearch-project-opensearch-php)[jsq/amazon-es-php

Support for using IAM authentication with the official Elasticsearch PHP client

9210.4M13](/packages/jsq-amazon-es-php)

PHPackages © 2026

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