PHPackages                             vuthaihoc/sqlout - 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. [Database &amp; ORM](/categories/database)
4. /
5. vuthaihoc/sqlout

ActiveLibrary[Database &amp; ORM](/categories/database)

vuthaihoc/sqlout
================

MySQL fulltext driver for Laravel Scout.

v1.0.0(1y ago)017MITPHPPHP ^8.0

Since Jun 17Pushed 1y agoCompare

[ Source](https://github.com/vuthaihoc/sqlout)[ Packagist](https://packagist.org/packages/vuthaihoc/sqlout)[ RSS](/packages/vuthaihoc-sqlout/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (6)Versions (2)Used By (0)

Sqlout
======

[](#sqlout)

Sqlout is a very simple MySQL driver for Laravel Scout. It indexes the data into a dedicated table of the MySQL database, and uses a fulltext index to search. It is meant for small-sized projects, for which bigger solutions such as ElasticSearch would be an overkill.

Sqlout is different than Scout 9's native `Database` engine because it indexes data in a separate, dedicated table, and uses a fulltext index. Sqlout has more features such as field weights and word stemming.

Sqlout is compatible with Laravel 5.8+ to 10.x and Scout 7.1+ / 8.x / 9.x / 10.x (credit goes to [ikari7789](https://github.com/ikari7789) for Laravel 9 and 10 / Scout 9 and 10 support).

Version Compatibility
---------------------

[](#version-compatibility)

LaravelScoutSqlout5.87.1 / 7.21.x / 2.06.x7.1 / 7.21.x / 2.06.x8.x2.07.x8.x2.08.x8.x3.x8.x / 9.x9.x4.x9.x / 10.x10.x5.xSetup
-----

[](#setup)

Require the package:

```
composer require baril/sqlout

```

Publish the configuration:

```
php artisan vendor:publish

```

If you're not using package discovery, manually add the service providers (Scout's and Sqlout's) to your `config/app.php` file:

```
return [
    // ...
    'providers' => [
        // ...
        Laravel\Scout\ScoutServiceProvider::class,
        Baril\Sqlout\SqloutServiceProvider::class,
    ],
];
```

Migrate your database:

```
php artisan sqlout:make-migration
php artisan migrate

```

This will create a `searchindex` table in your database (the table name can be customized in the config file).

If you want to index models that belong to different connections, you need a table for Sqlout on each connection. To create the table on a connection that is not the default connection, you can call the `sqlout:make-migration` command and pass the name of the connection:

```
php artisan sqlout:make-migration my_other_connection
php artisan migrate

```

Making a model searchable
-------------------------

[](#making-a-model-searchable)

```
use Baril\Sqlout\Searchable;

class Post extends Model
{
    use Searchable;

    protected $weights = [
        'title' => 4,
        'excerpt' => 2,
    ];

    public function toSearchableArray()
    {
        return [
            'title' => $this->post_title,
            'excerpt' => $this->post_excerpt,
            'body' => $this->post_content,
        ];
    }
}
```

The example above is similar to what is described in [Scout's documentation](https://laravel.com/docs/master/scout#configuration), with the following differences/additions:

- You'll notice that the model uses the `Baril\Sqlout\Searchable` trait instead of `Laravel\Scout\Searchable`.
- The `$weight` property can be used to "boost" some fields. The default value is 1.

Once this is done, you can index your data using Scout's Artisan command:

```
php artisan scout:import "App\Post"

```

Your models will also be indexed automatically on save.

Searching
---------

[](#searching)

### Basics

[](#basics)

```
$results = Post::search('this rug really tied the room together')->get();
$results = Post::search('the dude abides')->withTrashed()->get();
```

See [Scout's documentation](https://laravel.com/docs/master/scout#searching)for more details.

Sqlout's builder also provides the following additional methods:

```
// Restrict the search to some fields only:
$builder->only('title');
$builder->only(['title', 'excerpt']);
// (use the same names as in the toSearchableArray method)

// Retrieve the total number of results:
$nbHits = $builder->count();
```

### Using scopes

[](#using-scopes)

With Sqlout, you can also use your model scopes on the search builder, as if it was a query builder on the model itself. Similarly, all calls to the `where` method on the search builder will be forwarded to the model's query builder.

```
$results = Post::search('you see what happens larry')
    ->published() // the `published` scope is defined in the Post class
    ->where('date', '>', '2010-10-10')
    ->get();
```

> ⚠️ Keep in mind that these forwarded scopes will actually be applied to a subquery (the main query here being the one on the `searchindex` table). This means that for example a scope that adds an `order by` clause won't have any effect. See below for the proper way to order results.

If the name of your scope collides with the name of a method of the `Baril\Sqlout\Builder` object, you can wrap your scope into the `scope` method:

```
$results = Post::search('ve vant ze money lebowski')
    ->scope(function ($query) {
        $query->within('something');
    })
    ->get();
```

### Search modes

[](#search-modes)

MySQL's fulltext search comes in 3 flavours:

- natural language mode,
- natural language mode with query expansion,
- boolean mode.

Sqlout's default mode is "natural language" (but this can be changed in the config file).

You can also switch between all 3 modes on a per-query basis, by using the following methods:

```
$builder->inNaturalLanguageMode();
$builder->withQueryExpansion();
$builder->inBooleanMode();
```

### Ordering the results

[](#ordering-the-results)

If no order is specified, the results will be ordered by score (most relevant first). But you can also order the results by any column of your table.

```
$builder->orderBy('post_status', 'asc')->orderByScore();
// "post_status" is a column of the original table
```

In the example below, the results will be ordered by status first, and then by descending score.

### Filters, tokenizer, stopwords and stemming

[](#filters-tokenizer-stopwords-and-stemming)

In your config file, you can customize the way the indexed content and search terms will be processed:

```
return [
    // ...
    'sqlout' => [
        // ...
        'filters' => [ // anything callable (function name, closure...)
            'strip_tags',
            'html_entity_decode',
            'mb_strtolower',
            'strip_punctuation', // this helper is provided by Sqlout (see helpers.php)
        ],
        'token_delimiter' => '/[\s]+/',
        'minimum_length' => 2,
        'stopwords' => [
            'est',
            'les',
        ],
        'stemmer' => Wamania\Snowball\Stemmer\French::class,
    ],
];
```

In the example, the stemmer comes from the package [`wamania/php-stemmer`](https://github.com/wamania/php-stemmer), but any class with a `stem` method, or anything callable such as a closure, will do.

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance32

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 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

Unknown

Total

1

Last Release

700d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/2509658?v=4)[Stupid Dev](/maintainers/vuthaihoc)[@vuthaihoc](https://github.com/vuthaihoc)

---

Top Contributors

[![andrew-miller-rakuten](https://avatars.githubusercontent.com/u/159877857?v=4)](https://github.com/andrew-miller-rakuten "andrew-miller-rakuten (23 commits)")[![michaelbaril](https://avatars.githubusercontent.com/u/11444287?v=4)](https://github.com/michaelbaril "michaelbaril (18 commits)")[![mbwbd](https://avatars.githubusercontent.com/u/231652605?v=4)](https://github.com/mbwbd "mbwbd (11 commits)")[![ikari7789](https://avatars.githubusercontent.com/u/1041215?v=4)](https://github.com/ikari7789 "ikari7789 (2 commits)")[![vuthaihoc](https://avatars.githubusercontent.com/u/2509658?v=4)](https://github.com/vuthaihoc "vuthaihoc (1 commits)")

---

Tags

searchlaravelmysqlfulltextscout

###  Code Quality

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/vuthaihoc-sqlout/health.svg)

```
[![Health](https://phpackages.com/badges/vuthaihoc-sqlout/health.svg)](https://phpackages.com/packages/vuthaihoc-sqlout)
```

###  Alternatives

[kirschbaum-development/eloquent-power-joins

The Laravel magic applied to joins.

1.6k25.2M34](/packages/kirschbaum-development-eloquent-power-joins)[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[baril/sqlout

MySQL fulltext driver for Laravel Scout.

4512.9k](/packages/baril-sqlout)[mehdi-fathi/eloquent-filter

Eloquent Filter adds custom filters automatically to your Eloquent Models in Laravel.It's easy to use and fully dynamic, just with sending the Query Strings to it.

450191.6k1](/packages/mehdi-fathi-eloquent-filter)[jeroen-g/explorer

Next-gen Elasticsearch driver for Laravel Scout.

397612.3k](/packages/jeroen-g-explorer)[pmatseykanets/laravel-scout-postgres

PostgreSQL Full Text Search Driver for Laravel Scout

164213.7k2](/packages/pmatseykanets-laravel-scout-postgres)

PHPackages © 2026

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