PHPackages                             romanstruk/manticore-scout-engine - 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. romanstruk/manticore-scout-engine

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

romanstruk/manticore-scout-engine
=================================

Laravel Manticore Scout Engine

8.0.0(2mo ago)4818.1k↓16%7[3 issues](https://github.com/RomanStruk/manticore-scout-engine/issues)MITPHPPHP ^8.3

Since Jul 22Pushed 2mo ago4 watchersCompare

[ Source](https://github.com/RomanStruk/manticore-scout-engine)[ Packagist](https://packagist.org/packages/romanstruk/manticore-scout-engine)[ RSS](/packages/romanstruk-manticore-scout-engine/feed)WikiDiscussions 8.x Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (66)Used By (0)

Manticore Scout Engine
======================

[](#manticore-scout-engine)

[![Release](https://camo.githubusercontent.com/c810af9aa8fe71608a252801ef64b6fe28a2c2346c6414b3e92fc7e125de3196/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f526f6d616e537472756b2f6d616e7469636f72652d73636f75742d656e67696e653f7374796c653d666c61742d737175617265)](https://github.com/RomanStruk/manticore-scout-engine/releases)[![StandWithUkraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua/)

[!["Buy Me A Coffee"](https://camo.githubusercontent.com/9f44ce2dc3b3eecdd02598900866ffc518801df1932849703dae1e5ce5031070/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67)](https://buymeacoffee.com/romanstruk)

Manticore Engine for Laravel Scout

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

[](#installation)

Via Composer

```
$ composer require romanstruk/manticore-scout-engine
```

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

[](#configuration)

After installing Manticore Scout Engine, you should publish the Manticore configuration file using the vendor:publish Artisan command. This command will publish the manticore.php configuration file to your application's config directory:

```
php artisan vendor:publish --provider="RomanStruk\ManticoreScoutEngine\ManticoreServiceProvider"
```

```
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
```

### Configuring Search Driver

[](#configuring-search-driver)

Set up your search driver `manticore` in `.env` file

```
SCOUT_DRIVER=manticore
```

There is a choice between two ways to connect to the manticore

- http-client - `\Manticoresearch\Client` [github](https://github.com/manticoresoftware/manticoresearch-php)
- mysql-builder - `\RomanStruk\ManticoreScoutEngine\Builder` use mysql connection

Set up your engine in `.env` file

```
MANTICORE_ENGINE=http-client
```

### Configuring Driver Connection

[](#configuring-driver-connection)

For `http-client` in `.env` file

```
MANTICORE_HOST=127.0.0.1
MANTICORE_PORT=9308
```

For `mysql-builder` in `.env` file

```
MANTICORE_MYSQL_HOST=127.0.0.1
MANTICORE_MYSQL_PORT=9306
```

### Configuring Model Migration

[](#configuring-model-migration)

To create a migration, specify the required fields in the searchable model

```
public function scoutIndexMigration(): array
{
    return [
        'fields' => [
            'id' => ['type' => 'bigint'],
            'name' => ['type' => 'text'],
            'category' => ['type' => 'string stored indexed'],// string|text [stored|attribute] [indexed]
        ],
        'settings' => [
            'min_prefix_len' => '3',
            'min_infix_len' => '3',
            'prefix_fields' => 'name',
            'expand_keywords' => '1',
            //'engine' => 'columnar', // [default] row-wise - traditional storage available in Manticore Search out of the box; columnar - provided by Manticore Columnar Library
        ],
    ];
}
```

### Configuring query options

[](#configuring-query-options)

`max_matches` - Maximum amount of matches that the server keeps in RAM for each index and can return to the client. Default is 1000.

For queries with pagination, you can specify automatic parameter calculation `max_matches`Set up your `paginate_max_matches` in `manticore.php` config file

```
'paginate_max_matches' => 1000,
```

Set `null` for calculate offset + limit

As some characters are used as operators in the query string, they should be escaped to avoid query errors or unwanted matching conditions. Set up your `auto_escape_search_phrase` in `manticore.php` config file

```
'auto_escape_search_phrase' => true,
```

Set `false` for disable auto escape special symbols `!    "    $    '    (    )    -    /    <    @    \    ^    |    ~`

Other parameters for queries can be specified in the model

```
public function scoutMetadata(): array
{
    return [
        'cutoff' => 0,
        'max_matches' => 1000,
    ];
}
```

Config `paginate_max_matches` has higher priority than `scoutMetadata` `max_matches` option

Usage
-----

[](#usage)

Documentation for Scout can be found on the Laravel website.

Run artisan command for create Manticore index

```
php artisan manticore:index "App\Models\Product"
```

Manticore allows you to add "whereRaw" methods to your search queries.

```
use RomanStruk\ManticoreScoutEngine\Mysql\Builder;

$products = Product::search('Brand Name', function (Builder $builder) {
    return $builder
        ->whereAny('category_id', ['1', '2', '3'])
        ->where('column', '=', 'value')
//        ->whereIn('column', ['1', '2'])
//        ->whereNotIn('column', ['3', '4'])
//        ->whereAll('column', ['3', '4'])
//        ->whereNotAll('column', ['5', '6'])
//        ->whereAllMva('column', 'in', ['1', '2'])
//        ->whereAnyMva('column', 'not in', ['1', '2'])
        ->facet('category_id')
        ->inRandomOrder();
})->get();
```

### Quorum matching operator

[](#quorum-matching-operator)

Quorum matching operator introduces a kind of fuzzy matching. It will only match those documents that pass a given threshold of given words. The example above ("the world is a wonderful place"/3) will match all documents that have at least 3 of the 6 specified words.

```
use RomanStruk\ManticoreScoutEngine\Mysql\Builder;

$products = Product::search('the world is a wonderful place', function (Builder $builder) {
    return $builder->setQuorumMatchingOperator(3);
})->get();
```

Proximity distance is specified in words, adjusted for word count, and applies to all words within quotes. For instance, "cat dog mouse"~5 query means that there must be less than 8-word span which contains all 3 words, ie.

```
use RomanStruk\ManticoreScoutEngine\Mysql\Builder;

$products = Product::search('cat dog mouse', function (Builder $builder) {
    return $builder->setProximitySearchOperator(5);
})->get();
```

### Autocomplete

[](#autocomplete)

Autocomplete (or word completion) is a feature in which an application predicts the rest of a word a user is typing. On websites, it's used in search boxes, where a user starts to type a word, and a dropdown with suggestions pops up so the user can select the ending from the list.

```
use RomanStruk\ManticoreScoutEngine\Mysql\Builder;

//[doc] My cat loves my dog. The cat (Felis catus) is a domestic species of small carnivorous mammal.

$autocomplete = Product::search('my*',function (Builder $builder) {
    return $builder->autocomplete(['"','^'], true); // "" ^ * allow full-text operators; stats - Show statistics of keywords, default is 0
})->raw();
// $autocomplete "my", "my cat", "my dog"
```

### Spell correction

[](#spell-correction)

```
use RomanStruk\ManticoreScoutEngine\Mysql\Builder;

//[doc] Crossbody Bag with Tassel
//[doc] microfiber sheet set
//[doc] Pet Hair Remover Glove

$result = Product::search('bagg with tasel',function (Builder $builder) {
    return $builder->spellCorrection(true) // correct first word
})->raw();
// $result 0 => ['suggest' => "bag"]

$result = Product::search('bagg with tasel',function (Builder $builder) {
    return $builder->spellCorrection() // correct last word
})->raw();
// $result 0 => ['suggest' => "tassel"]

$result = Product::search('bagg with tasel',function (Builder $builder) {
    return $builder->spellCorrection(false, true) // correct last word and return sentence
})->raw();
// $result 0 => ['suggest' => "bagg with tassel"]
```

### Highlighting

[](#highlighting)

Highlighting enables you to obtain highlighted text fragments (referred to as snippets) from documents containing matching keywords.

```
use RomanStruk\ManticoreScoutEngine\Mysql\Builder;

//[doc] My cat loves my dogs.

$highlight = Product::search('dogs',
    fn(Builder $builder) => $builder->highlight()->select(['id', 'name'])
)->raw();
// $highlight['hits'] [id => 1, name => 'My cat loves my dogs.', 'highlight' => 'My cat loves my dogs.']
```

or

```
use RomanStruk\ManticoreScoutEngine\Mysql\Builder;

//[doc] title => My cat loves my dogs. id => 1000

$highlight = Product::search('dogs',
    fn(Builder $builder) => $builder->highlight()->select(['id', 'title'])
)->get();
// $highlight->getHighlight()[1000] => 'My cat loves my dogs.'
```

### Percolate Query

[](#percolate-query)

To create a migration, specify the required fields in the searchable model

```
public function scoutIndexMigration(): array
{
    return [
            'fields' => [
                'title' => ['type' => 'text'],
                'color' => ['type' => 'string'],
            ],
            'settings' => [
                'type' => 'pq'
            ],
    ];
}

public function toSearchableArray(): array
{
    return array_filter([
        'id' => $this->name,
        'query' => "@title {$this->title}",
        'filters' => $this->color ? "color='{$this->color}'" : null,
    ]);
}
```

Percolate queries are also known as Persistent queries, Prospective search, document routing, search in reverse, and inverse search. [https://manual.manticoresearch.com/Searching/Percolate\_query#Percolate-Query](https://manual.manticoresearch.com/Searching/Percolate_query#Percolate-Query)

```
use RomanStruk\ManticoreScoutEngine\Mysql\Builder;

$products = PercolateProduct::search(json_encode(['title' =>'Beautiful shoes']),
    fn(Builder $builder) => $builder->percolateQuery(docs: true, docsJson: true)
)->get();
```

### KNN

[](#knn)

K-nearest neighbor vector search

Added the ability to create records with the `float_vector` field type

```
use RomanStruk\ManticoreScoutEngine\Mysql\ManticoreVector;

public function scoutIndexMigration(): array
{
    return [
        'fields' => [
            'id' => ['type' => 'bigint'],
            'name' => ['type' => 'text'],
            'vector' => ['type' => "float_vector knn_type='hnsw' knn_dims='4' hnsw_similarity='l2'"],
        ],
        'settings' => [],
    ];
}

public function toSearchableArray(): array
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'vector' => new ManticoreVector(...$this->vector), // $this->vector is array
    ];
}
```

Currently, the implementation is only available using `whereRaw`.

```
$results = SimilarProduct::search('bar', function (Builder $query) {
    return $query->whereRaw("knn ( vector, 5, (0.286569,-0.031816,0.066684,0.032926), 2000 )");
})->get();
```

Please note that when using the "Find similar docs by id" syntax, you need to discard meta `discardMeta()`. Exact information about the number of results is not available

```
$results = SimilarProduct::search('foo', function (Builder $query) {
    return $query->whereRaw("knn ( vector, 5, 1 )")->discardMeta();
})->get();
```

### Join Table

[](#join-table)

Table joins in Manticore Search enable you to combine documents from two tables by matching related columns. This functionality allows for more complex queries and enhanced data retrieval across multiple tables.

```
use App\Models\Category;
use App\Models\Product;

$categoryTable = (new Category)->searchableAs();

$searchable = Product::search('some search query', static fn(Builder $builder)
    => $builder
    ->select(['id', DB::raw($categoryTable.'.name as name')])
    ->join($categoryTable, $categoryTable.'.id', '=', $builder->index.'.category_id') // inner join table categories
    ->leftJoin($categoryTable, $categoryTable.'.id', '=', $builder->index.'.category_id') // left join table categories
    ->orderBy('id'),
)->raw();
```

**Manticore Docs**LEFT JOIN: Returns all rows from the left table and the matched rows from the right table. If there is no match, NULL values are returned for the right table's columns.

**WARNING**there is a problem that "LEFT JOIN" does not return "NULL" in the classic php sense but returns a string with the text "NULL"

Change log
----------

[](#change-log)

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

Testing
-------

[](#testing)

```
$ composer test
```

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

[](#contributing)

Please see [contributing.md](contributing.md) for details and a todolist.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

License
-------

[](#license)

MIT. Please see the [license file](license.md) for more information.

###  Health Score

59

—

FairBetter than 99% of packages

Maintenance87

Actively maintained with recent releases

Popularity40

Moderate usage in the ecosystem

Community16

Small or concentrated contributor base

Maturity77

Established project with proven stability

 Bus Factor1

Top contributor holds 81% 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 ~21 days

Recently: every ~59 days

Total

65

Last Release

60d ago

Major Versions

4.5.6 → 5.2.82023-05-16

4.6.0 → 5.6.02023-08-31

5.x-dev → 6.0.02024-03-20

6.x-dev → 7.0.02025-03-03

7.x-dev → 8.0.02026-03-19

PHP version history (5 changes)1.0.0PHP ^7.4

5.0.0PHP ^7.4|^8.1

5.2.7PHP ^8.1

6.0.0PHP ^8.2

8.0.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/725e1988d98adf61dc777725d289f272c8b6fbcfc415b1252caeaac14c594174?d=identicon)[RomanStruk](/maintainers/RomanStruk)

---

Top Contributors

[![RomanStruk](https://avatars.githubusercontent.com/u/19497911?v=4)](https://github.com/RomanStruk "RomanStruk (34 commits)")[![cevin](https://avatars.githubusercontent.com/u/338110?v=4)](https://github.com/cevin "cevin (6 commits)")[![ankogit](https://avatars.githubusercontent.com/u/20892701?v=4)](https://github.com/ankogit "ankogit (1 commits)")[![ramir1](https://avatars.githubusercontent.com/u/971933?v=4)](https://github.com/ramir1 "ramir1 (1 commits)")

---

Tags

laravelscoutmanticore

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/romanstruk-manticore-scout-engine/health.svg)

```
[![Health](https://phpackages.com/badges/romanstruk-manticore-scout-engine/health.svg)](https://phpackages.com/packages/romanstruk-manticore-scout-engine)
```

###  Alternatives

[jeroen-g/explorer

Next-gen Elasticsearch driver for Laravel Scout.

397612.3k](/packages/jeroen-g-explorer)[teamtnt/laravel-scout-tntsearch-driver

Driver for Laravel Scout search package based on https://github.com/teamtnt/tntsearch

1.1k2.5M28](/packages/teamtnt-laravel-scout-tntsearch-driver)[algolia/scout-extended

Scout Extended extends Laravel Scout adding algolia-specific features

4186.3M6](/packages/algolia-scout-extended)[vanry/laravel-scout-tntsearch

包含中文分词的 Laravel Scout TNTSearch 驱动，支持 scws, phpanalysis 和 jieba 分词。

17811.8k1](/packages/vanry-laravel-scout-tntsearch)[baijunyao/laravel-scout-elasticsearch

Elasticsearch Driver for Laravel Scout

8023.7k1](/packages/baijunyao-laravel-scout-elasticsearch)[optimistdigital/laravel-scout-batch-searchable

This Laravel package adds a BatchSearchable trait to allow batching Scout updates.

3010.9k](/packages/optimistdigital-laravel-scout-batch-searchable)

PHPackages © 2026

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