PHPackages                             greensight/laravel-elastic-query - 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. greensight/laravel-elastic-query

Abandoned → [ensi/laravel-elastic-query](/?search=ensi%2Flaravel-elastic-query)ArchivedLibrary[Search &amp; Filtering](/categories/search)

greensight/laravel-elastic-query
================================

0.2.0(4y ago)2121MITPHPPHP ^8.0

Since Jul 21Pushed 4y agoCompare

[ Source](https://github.com/greensight/laravel-elastic-query)[ Packagist](https://packagist.org/packages/greensight/laravel-elastic-query)[ RSS](/packages/greensight-laravel-elastic-query/feed)WikiDiscussions master Synced yesterday

READMEChangelog (4)Dependencies (7)Versions (6)Used By (1)

Laravel Elastic Query
=====================

[](#laravel-elastic-query)

`Deprecated, use https://github.com/ensi-platform/laravel-telemetry instead`

Working with Elasticsearch in an Eloquent-like fashion.

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

[](#installation)

You can install the package via composer:

1. `composer require greensight/laravel-elastic-query`
2. Set `ELASTICSEARCH_HOSTS` in your `.env` file. `,` can be used as a delimeter.

Basic usage
-----------

[](#basic-usage)

Let's create and index class. It's someting like Eloquent model.

```
use Greensight\LaravelElasticQuery\ElasticIndex;

class ProductsIndex extends ElasticIndex
{
    protected string $name = 'test_products';
    protected string $tiebreaker = 'product_id';
}
```

You should set a unique in document attribute name in `$tiebreaker`. It is used as an additional sort in `search_after`

Now we can get some documents

```
$searchQuery = ProductsIndex::query();

$hits = $searchQuery
             ->where('rating', '>=', 5)
             ->whereDoesntHave('offers', fn(BoolQuery $query) => $query->where('seller_id', 10)->where('active', false))
             ->sortBy('rating', 'desc')
             ->sortByNested('offers', fn(SortableQuery $query) => $query->where('active', true)->sortBy('price', mode: 'min'))
             ->take(25)
             ->get();
```

### Filtering

[](#filtering)

```
$searchQuery->where('field', 'value');
$searchQuery->where('field', '>', 'value'); // supported operators: `=` `!=` `>` `=` `whereNot('field', 'value'); // equals `where('field', '!=', 'value')`
```

```
$searchQuery->whereIn('field', ['value1', 'value2']);
$searchQuery->whereNotIn('field', ['value1', 'value2']);
```

```
$searchQuery->whereNull('field');
$searchQuery->whereNotNull('field');
```

```
$searchQuery->whereHas('nested_field', fn(BoolQuery $subQuery) => $subQuery->where('field_in_nested', 'value'));
$searchQuery->whereDoesntHave(
    'nested_field',
    function (BoolQuery $subQuery) {
        $subQuery->whereHas('nested_field', fn(BoolQuery $subQuery2) => $subQuery2->whereNot('field', 'value'));
    }
);
```

`nested_field` must have `nested` type. Subqueries cannot use fields of main document only subdocument.

### Sorting

[](#sorting)

```
$searchQuery->sortBy('field', 'desc', 'max'); // field is from main document
$searchQuery->sortByNested(
    'nested_field',
    fn(SortableQuery $subQuery) => $subQuery->where('field_in_nested', 'value')->sortBy('field')
);
```

Second attribute is a direction. It supports `asc` and `desc` values. Defaults to `asc`.
Third attribute - sorting type. List of supporting types: `min, max, avg, sum, median`. Defaults to `min`.

There are also dedicated sort methods for each sort type.

```
$searchQuery->minSortBy('field', 'asc');
$searchQuery->maxSortBy('field', 'asc');
$searchQuery->avgSortBy('field', 'asc');
$searchQuery->sumSortBy('field', 'asc');
$searchQuery->medianSortBy('field', 'asc');
```

### Pagination

[](#pagination)

#### Offset Pagination

[](#offset-pagination)

```
$page = $searchQuery->paginate(15, 45);
```

Offset pagination returns total documents count as `total` and current position as `size/offset`.

#### Cursor pagination

[](#cursor-pagination)

```
$page = $searchQuery->cursorPaginate(10);
$pageNext = $searchQuery->cursorPaginate(10, $page->next);
```

`current`, `next`, `previous` is returned in this case instead of `total`, `size` and `offset`. You can check Laravel docs for more info about cursor pagination.

Aggregation
-----------

[](#aggregation)

Aggregaction queries can be created like this

```
$aggQuery = ProductsIndex::aggregate();

/** @var \Illuminate\Support\Collection $aggs */
$aggs = $aggQuery
            ->where('active', true)
            ->terms('codes', 'code')
            ->nested(
                'offers',
                fn(AggregationsBuilder $builder) => $builder->where('seller_id', 10)->minmax('price', 'price')
            );

$aggs

```

Type of `$aggs->price` is `MinMax`. Type of `$aggs->codes` is `BucketCollection`. Aggregate names must be unique for whole query.

### Aggregate types

[](#aggregate-types)

Get all variants of attribute values:

```
$aggQuery->terms('agg_name', 'field');
```

Get min and max attribute values. E.g for date:

```
$aggQuery->minmax('agg_name', 'field');
```

Aggregation plays nice with nested documents.

```
$aggQuery->nested('nested_field', function (AggregationsBuilder $builder) {
    $builder->terms('name', 'field_in_nested');
});
```

There is also a special virtual `composite` aggregate on the root level. You can set special conditions using it.

```
$aggQuery->composite(function (AggregationsBuilder $builder) {
    $builder->where('field', 'value')
        ->whereHas('nested_field', fn(BoolQuery $query) => $query->where('field_in_nested', 'value2'))
        ->terms('field1', 'agg_name1')
        ->minmax('field2', 'agg_name2');
});
```

Query Log
---------

[](#query-log)

Just like Eloquent ElasticQuery has its own query log, but you need to enable it manually Each message contains `indexName`, `query` and `timestamp`

```
ElasticQuery::enableQueryLog();

/** @var \Illuminate\Support\Collection|Greensight\LaravelElasticQuery\Debug\QueryLogRecord[] $records */
$records = ElasticQuery::getQueryLog();

ElasticQuery::disableQueryLog();
```

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

[](#contributing)

Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.

### Testing

[](#testing)

1. composer install
2. npm i
3. Start Elasticsearch in your preferred way.
4. Copy `phpunit.xml.dist` to `phpunit.xml` and set correct env variables there
5. composer test

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

License
-------

[](#license)

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

###  Health Score

24

—

LowBetter than 32% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 73.3% 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 ~20 days

Total

4

Last Release

1693d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/58d505cd6b2551974b0c076d133fd9a3c9cd635bbf308adb17a6399bd3b63232?d=identicon)[Arrilot](/maintainers/Arrilot)

---

Top Contributors

[![arrilot](https://avatars.githubusercontent.com/u/2826480?v=4)](https://github.com/arrilot "arrilot (11 commits)")[![zix2](https://avatars.githubusercontent.com/u/51262118?v=4)](https://github.com/zix2 "zix2 (4 commits)")

---

Tags

laravelelasticsearch

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/greensight-laravel-elastic-query/health.svg)

```
[![Health](https://phpackages.com/badges/greensight-laravel-elastic-query/health.svg)](https://phpackages.com/packages/greensight-laravel-elastic-query)
```

###  Alternatives

[mailerlite/laravel-elasticsearch

An easy way to use the official PHP ElasticSearch client in your Laravel applications.

934529.3k2](/packages/mailerlite-laravel-elasticsearch)[jeroen-g/explorer

Next-gen Elasticsearch driver for Laravel Scout.

397612.3k](/packages/jeroen-g-explorer)[baijunyao/laravel-scout-elasticsearch

Elasticsearch Driver for Laravel Scout

8023.7k1](/packages/baijunyao-laravel-scout-elasticsearch)

PHPackages © 2026

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