Elastic Bridge: Eloquent Queries for Elasticsearch in Laravel | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. [Laravel](https://www.msaied.com/public/articles?category=laravel)
6. /
7. Elastic Bridge: Eloquent-Style Queries for Elasticsearch and OpenSearch in Laravel

   [Laravel](https://www.msaied.com/public/articles?category=laravel) [Composer Pacakge](https://www.msaied.com/public/articles?category=composer-pacakge) 

 Elastic Bridge: Eloquent-Style Queries for Elasticsearch and OpenSearch in Laravel
===================================================================================

 Elastic Bridge is a Laravel package that lets you query Elasticsearch and OpenSearch using a fluent, Eloquent-style API — no hand-written JSON DSL required. It supports full-text search, filters, aggregations, cursor pagination, and testing utilities.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 29 Sep 2026 · Updated 29 Sep 2026 · 4 min read

ShareCopy linkCopied

 ![Elastic Bridge: Eloquent-Style Queries for Elasticsearch and OpenSearch in Laravel](https://cdn.msaied.com/717/c7051bd4ebce37109a2149b0bd8cbdd9.png) 

  On this page +1. [Elastic Bridge: Eloquent-Style Queries for Elasticsearch and OpenSearch](#elastic-bridge-eloquent-style-queries-for-elasticsearch-and-opensearch)
2. [Define a Bridge for Your Index](#define-a-bridge-for-your-index)
3. [Combine Full-Text Search and Filters](#combine-full-text-search-and-filters)
4. [Retrieve Documents and Aggregations Together](#retrieve-documents-and-aggregations-together)
5. [Test Without a Running Search Cluster](#test-without-a-running-search-cluster)
6. [Installation and Backend Configuration](#installation-and-backend-configuration)
7. [Key Takeaways](#key-takeaways)

 Elastic Bridge: Eloquent-Style Queries for Elasticsearch and OpenSearch
-----------------------------------------------------------------------

Writing raw JSON DSL for Elasticsearch or OpenSearch queries gets tedious fast. [Elastic Bridge](https://github.com/lacasera/elastic-bridge), a Laravel package by Agyenim Boateng, solves that by giving you a fluent, Eloquent-style API for both search backends. You define a class for an index, then chain PHP methods to build full-text searches and filters without touching a single JSON structure.

### Define a Bridge for Your Index

The package calls its model classes *bridges*. Generate one with Artisan:

```bash
php artisan make:bridge HotelRoom

```

Each bridge extends the package's base class. Set the target index with a protected property:

```php
namespace App\Bridges;

use Lacasera\ElasticBridge\ElasticBridge;

class HotelRoom extends ElasticBridge
{
    protected $index = 'hotel-rooms';
}

```

Bridges support a `$casts` property for converting document attributes (including dates and enums), plus accessors and mutators via Laravel's `Attribute` class — patterns that will feel immediately familiar to any Eloquent user.

### Combine Full-Text Search and Filters

The fluent API lets you mix match clauses, exact-term filters, range filters, sorting, and cursor pagination in a single chain:

```php
$rooms = HotelRoom::asBoolean()
    ->mustMatch('city', 'accra')
    ->filterByTerm('code', 'usd')
    ->filterByRange('price', 500, 'lte')
    ->orderBy('price', 'ASC')
    ->cursorPaginate(15)
    ->get(['name', 'price', 'code']);

```

`mustMatch()` builds a match clause; `filterByTerm()` adds an exact term filter. For searching across multiple fields, use `multiMatch()`:

```php
$rooms = HotelRoom::multiMatch(
    field: ['advertiser', 'service_type'],
    query: 'hotel',
)->get();

```

In v2, `multiMatch()` and `matchPhrase()` automatically nest inside a boolean query. Cursor pagination relies on Elasticsearch's `search_after` mechanism and requires a deterministic sort order; the returned collection exposes next and previous sort values through `links()`.

### Retrieve Documents and Aggregations Together

You can attach aggregations directly to a document query:

```php
$rooms = HotelRoom::asBoolean()
    ->mustMatch('city', 'accra')
    ->withAggregate('avg', 'price')
    ->get();

$averagePrice = $rooms->priceAvg();

```

In v2, aggregation results belong to the returned collection instance, so separate result sets each retain their own aggregation values — useful in long-lived queue workers. The package also returns a `Stats` object for `stats()` queries and a collection of bucket objects for `histogram()`.

### Test Without a Running Search Cluster

Elastic Bridge ships a `fake()` helper that supplies a mock search response, and a `toQuery()` method that lets you inspect the generated query structure:

```php
public function test_builds_currency_filter(): void
{
    HotelRoom::fake([
        'hits' => [
            'total' => ['value' => 0, 'relation' => 'eq'],
            'hits' => [],
        ],
    ]);

    $query = HotelRoom::asBoolean()
        ->filterByTerm('code', 'usd')
        ->toQuery();

    $this->assertSame([
        'query' => [
            'bool' => [
                'filter' => [
                    ['term' => ['code' => 'usd']],
                ],
            ],
        ],
    ], $query);
}

```

This lets you assert on query structure in CI without spinning up an Elasticsearch or OpenSearch instance.

### Installation and Backend Configuration

Requirements: PHP 8.2 or 8.3, Laravel 10/11/12, and Elasticsearch 8.x or OpenSearch 2.x.

```bash
composer require lacasera/elastic-bridge
php artisan vendor:publish --tag="elastic-bridge-config"

```

Set `SEARCH_DRIVER` to `elasticsearch` or `opensearch` in your environment, then configure the connection in `config/elasticbridge.php`. Both drivers share the same fluent query API. Authentication options include basic auth, API keys, and AWS SigV4 for OpenSearch (requires the optional AWS SDK dependency).

The package also ships a development skill for [Laravel Boost v2](https://laravel-news.com/laravel-boost-v2), making its guidance available to coding agents via `php artisan boost:install`.

### Key Takeaways

- **Eloquent-style API** — chain PHP methods instead of writing JSON DSL for Elasticsearch and OpenSearch queries.
- **Dual backend support** — switch between Elasticsearch 8.x and OpenSearch 2.x with a single environment variable.
- **Aggregations on collections** — `withAggregate()` attaches aggregation results to the returned collection instance.
- **Cursor pagination** — built on `search_after` with `links()` helpers for next/previous navigation.
- **No cluster needed for tests** — `fake()` and `toQuery()` let you unit-test query logic in isolation.
- **Laravel Boost integration** — package guidance is available to AI coding agents out of the box.

---

*Source: [Laravel News — Elastic Bridge: Eloquent-Style Queries for Elasticsearch and OpenSearch](https://laravel-news.com/elastic-bridge)*

- [Laravel](https://www.msaied.com/public/articles?search=Laravel)
- [Elasticsearch](https://www.msaied.com/public/articles?search=Elasticsearch)
- [OpenSearch](https://www.msaied.com/public/articles?search=OpenSearch)
- [Laravel Package](https://www.msaied.com/public/articles?search=Laravel%20Package)
- [Full-Text Search](https://www.msaied.com/public/articles?search=Full-Text%20Search)

 Frequently asked questions 
---------------------------

  Does Elastic Bridge work with both Elasticsearch and OpenSearch?Yes. You set the `SEARCH\_DRIVER` environment variable to either `elasticsearch` or `opensearch`. Both backends use the same fluent query API, so no application code changes are needed when switching drivers.

   How do you test Elastic Bridge queries without a running search cluster?Use the `fake()` method to supply a mock search response, then call `toQuery()` to retrieve the generated query array and assert on its structure. This allows full unit testing of query logic in CI environments without Elasticsearch or OpenSearch installed.

   What is the difference between mustMatch() and filterByTerm() in Elastic Bridge?`mustMatch()` builds a full-text match clause inside a boolean query, while `filterByTerm()` adds an exact term filter. The distinction mirrors the underlying search engine query structure: match clauses are scored, term filters are not.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://www.msaied.com/public#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://www.msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleUnlearn.dev Goes Free for a Weekend: October 10 and 11](https://www.msaied.com/public/articles/unlearndev-goes-free-for-a-weekend-october-10-and-11) [Next articleLaravel Queues in Production: Dead-Letter Patterns, Retry Strategies, and Observability](https://www.msaied.com/public/articles/laravel-queues-in-production-dead-letter-patterns-retry-strategies-and-observability)  

   On this page
-------------

1. [Elastic Bridge: Eloquent-Style Queries for Elasticsearch and OpenSearch](#elastic-bridge-eloquent-style-queries-for-elasticsearch-and-opensearch)
2. [Define a Bridge for Your Index](#define-a-bridge-for-your-index)
3. [Combine Full-Text Search and Filters](#combine-full-text-search-and-filters)
4. [Retrieve Documents and Aggregations Together](#retrieve-documents-and-aggregations-together)
5. [Test Without a Running Search Cluster](#test-without-a-running-search-cluster)
6. [Installation and Backend Configuration](#installation-and-backend-configuration)
7. [Key Takeaways](#key-takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/740/cce86edc21eddcbdd2f2454fadaf9c70.png)  · 3 min read### The Pipeline Pattern in Laravel: Custom Pipelines Beyond Middleware

5 Oct 2026 ](https://www.msaied.com/public/articles/the-pipeline-pattern-in-laravel-custom-pipelines-beyond-middleware-1) [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://www.msaied.com/public/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://www.msaied.com/public/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/public/sitemap.xml)
