Elastic Bridge: Eloquent Queries for Elasticsearch in Laravel | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Elastic Bridge: Eloquent-Style Queries for Elasticsearch and OpenSearch in Laravel        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 in Laravel](https://cdn.msaied.com/717/c7051bd4ebce37109a2149b0bd8cbdd9.png)

 [  Laravel ](https://msaied.com/articles?category=laravel) [  Composer Pacakge ](https://msaied.com/articles?category=composer-pacakge)  #Laravel   #Elasticsearch   #OpenSearch   #Laravel Package   #Full-Text Search  

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

     29 Sep 2026      4 min read    ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said  

       Table of contents

1. [  01   Elastic Bridge: Eloquent-Style Queries for Elasticsearch and OpenSearch  ](#elastic-bridge-eloquent-style-queries-for-elasticsearch-and-opensearch)
2. [  02   Define a Bridge for Your Index  ](#define-a-bridge-for-your-index)
3. [  03   Combine Full-Text Search and Filters  ](#combine-full-text-search-and-filters)
4. [  04   Retrieve Documents and Aggregations Together  ](#retrieve-documents-and-aggregations-together)
5. [  05   Test Without a Running Search Cluster  ](#test-without-a-running-search-cluster)
6. [  06   Installation and Backend Configuration  ](#installation-and-backend-configuration)
7. [  07   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)*

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Felastic-bridge-eloquent-style-queries-for-elasticsearch-and-opensearch-in-laravel&text=Elastic+Bridge%3A+Eloquent-Style+Queries+for+Elasticsearch+and+OpenSearch+in+Laravel) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Felastic-bridge-eloquent-style-queries-for-elasticsearch-and-opensearch-in-laravel) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  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. 

      Q02  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. 

      Q03  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. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![Laravel Release Cycle: Versions, Support Policy, and Dates](https://cdn.msaied.com/718/05d0e66985cc7bda5c0be6c37bb8da65.png) Laravel Release Cycle Support Policy 

### Laravel Release Cycle: Versions, Support Policy, and Dates

Laravel ships one major version per year in Q1, with weekly minor and patch releases in between. Here is every...

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

 29 Sep 2026     4 min read  

  Read    

 ](https://msaied.com/articles/laravel-release-cycle-versions-support-policy-and-dates) [ ![Laravel Queues in Production: Dead-Letter Patterns, Retry Strategies, and Observability](https://cdn.msaied.com/716/262173aca18154738c1257f3a77cd2fa.png) laravel queues production 

### Laravel Queues in Production: Dead-Letter Patterns, Retry Strategies, and Observability

Beyond basic queue configuration: how to design retry budgets, route failed jobs to dead-letter queues, emit s...

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

 29 Sep 2026     1 min read  

  Read    

 ](https://msaied.com/articles/laravel-queues-in-production-dead-letter-patterns-retry-strategies-and-observability) [ ![Unlearn.dev Goes Free for a Weekend: October 10 and 11](https://cdn.msaied.com/715/4b8c50b8b926a79685bcbc80d767f519.png) AI workflows Laravel developer education 

### Unlearn.dev Goes Free for a Weekend: October 10 and 11

Unlearn.dev is dropping its paywall on October 10–11, giving Laravel developers free access to three complete...

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

 28 Sep 2026     3 min read  

  Read    

 ](https://msaied.com/articles/unlearndev-goes-free-for-a-weekend-october-10-and-11) 

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

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
