mailerlite/laravel-elasticsearch

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

Maintainers

Package info

github.com/mailerlite/laravel-elasticsearch

pkg:composer/mailerlite/laravel-elasticsearch

Transparency log

Fund package maintenance!

mailerlite

Statistics

Installs: 614 282

Dependents: 1

Suggesters: 0

Stars: 936

Open Issues: 4

12.0.0 2026-07-06 08:33 UTC

README

An easy way to use the official Elastic Search client in your Laravel applications.

Build Status Total Downloads Latest Stable Version License

Requirements

  • PHP 8.2 or higher (Laravel 13 requires PHP 8.3)
  • Laravel 11, 12 or 13
  • An Elasticsearch 8.x cluster

Installation

Install the current version of the mailerlite/laravel-elasticsearch package via composer:

composer require mailerlite/laravel-elasticsearch

This version of the package targets Elasticsearch 8.x. If you are running an older version of Elasticsearch, install the matching major version of this package:

Elasticsearch Package version
8.x ^12
7.x ^11

For example, to use Elasticsearch 7, install version ^11. Its documentation lives on the 11.x branch:

composer require mailerlite/laravel-elasticsearch:^11

Note

Upgrading from Elasticsearch 7? Version 12 moves to the Elasticsearch 8.x client, which introduces breaking changes (new namespace, response objects and removed configuration options). See UPGRADING.md for the full migration guide.

Configuration

The package's service provider is registered automatically.

Publish the configuration file:

php artisan vendor:publish --provider="MailerLite\LaravelElasticsearch\ServiceProvider"

Alternative configuration method via .env file

After you publish the configuration file as suggested above, you may configure ElasticSearch by adding the following to your application's .env file (with appropriate values):

ELASTICSEARCH_HOST=localhost
ELASTICSEARCH_PORT=9200
ELASTICSEARCH_SCHEME=http
ELASTICSEARCH_USER=
ELASTICSEARCH_PASS=

If you are logging in via API keys, you will need to fill in these values:

ELASTICSEARCH_API_ID=
ELASTICSEARCH_API_KEY=

Connecting to AWS Elasticsearch Service

If you are connecting to ElasticSearch instances on Amazon AWS, then you'll also need to composer require aws/aws-sdk-php:^3.80 and add the following to your .env file:

AWS_ELASTICSEARCH_ENABLED=true
AWS_REGION=...
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...

If you have to use another authentication method having custom credentials (i.e. instanceProfile()), you have to publish the configuration file and use the aws_credentials:

<?php
// config/elasticsearch.php

$provider = \Aws\Credentials\CredentialProvider::instanceProfile();
$memoizedProvider = \Aws\Credentials\CredentialProvider::memoize($provider);
$credentials = $memoizedProvider()->wait();

...

'hosts' => [
    [
        'host'            => env('ELASTICSEARCH_HOST', 'localhost'),
        // For local development, the default Elasticsearch port is 9200.
        // If you are connecting to an Elasticsearch instance on AWS, you probably want to set this to null
        'port'            => env('ELASTICSEARCH_PORT', 9200),
        'scheme'          => env('ELASTICSEARCH_SCHEME', null),
        'user'            => env('ELASTICSEARCH_USER', null),
        'pass'            => env('ELASTICSEARCH_PASS', null),

        // If you are connecting to an Elasticsearch instance on AWS, you will need these values as well
        'aws'             => env('AWS_ELASTICSEARCH_ENABLED', false),
        'aws_region'      => env('AWS_REGION', ''),
        'aws_key'         => env('AWS_ACCESS_KEY_ID', ''),
        'aws_secret'      => env('AWS_SECRET_ACCESS_KEY', ''),
        'aws_credentials' => $credentials,
    ],
],

If you have a job that runs in supervisor, you have to use the Closure. This way the credentials will be renewed at runtime.

<?php
// config/elasticsearch.php

$provider = \Aws\Credentials\CredentialProvider::instanceProfile();
$memoizedProvider = \Aws\Credentials\CredentialProvider::memoize($provider);

...

'hosts' => [
    [
        ...
        'aws_credentials' => $memoizedProvider
    ],
],

If you are using php artisan config:cache, you cannot have the Closure in your config file, call it like this:

<?php
// config/elasticsearch.php

...

'hosts' => [
    [
        ...
        'aws_credentials' => [\Aws\Credentials\CredentialProvider::class, 'defaultProvider'],
    ],
],

Security and TLS (Elasticsearch 8.x)

Elasticsearch 8 enables TLS and authentication by default. When connecting to a secured cluster you typically need to:

  • Set the scheme to https:

    ELASTICSEARCH_SCHEME=https
  • Provide credentials, either basic auth (ELASTICSEARCH_USER / ELASTICSEARCH_PASS) or an API key (ELASTICSEARCH_API_ID / ELASTICSEARCH_API_KEY).

  • If the cluster uses a self-signed certificate, point sslVerification at the CA bundle (e.g. the http_ca.crt generated by Elasticsearch) in your published config file:

    // config/elasticsearch.php
    'sslVerification' => '/path/to/http_ca.crt',

    For local development only, you can disable certificate verification with 'sslVerification' => false (not recommended in production).

Usage

The Elasticsearch facade is just an entry point into the ES client, so previously you might have used:

use Elastic\Elasticsearch\ClientBuilder;

$data = [
    'body' => [
        'testField' => 'abc'
    ],
    'index' => 'my_index',
    'id' => 'my_id',
];

$client = ClientBuilder::create()->build();
$return = $client->index($data);

You can now replace those last two lines with simply:

use Elasticsearch;

$return = Elasticsearch::index($data);

That will run the command on the default connection. You can run a command on any connection (see the defaultConnection setting and connections array in the configuration file).

$return = Elasticsearch::connection('connectionName')->index($data);

The official Elasticsearch 8.x client no longer returns plain arrays. Every call returns an Elastic\Elasticsearch\Response\Elasticsearch object that implements ArrayAccess, so you can keep accessing keys directly ($return['_id']) or convert it explicitly. By default the client also throws an Elastic\Elasticsearch\Exception\ClientResponseException on 4xx responses and a ServerResponseException on 5xx responses. For HEAD-style endpoints such as indices()->exists() and ping(), resolve the result with ->asBool().

Convert a response explicitly with one of:

$response = Elasticsearch::info();

$response->asArray();   // body as associative array
$response->asObject();  // body as stdClass
$response->asString();  // raw JSON string
$response->asBool();    // true for a 2xx status code

For example, running a search and reading the hits:

$response = Elasticsearch::search([
    'index' => 'my_index',
    'body'  => [
        'query' => [
            'match' => ['testField' => 'abc'],
        ],
    ],
]);

$hits = $response['hits']['hits'];          // via ArrayAccess
// or
$hits = $response->asArray()['hits']['hits'];

Instead of the facade, you can also use dependency injection or the application container to get the ES service object:

// using injection:
public function handle(\MailerLite\LaravelElasticsearch\Manager $elasticsearch)
{
    $elasticsearch->ping();
}

// using the application container:
$elasticsearch = app('elasticsearch');

Advanced Usage

Because the package is a wrapper around the official Elastic client, you can do pretty much anything with this package. Not only can you perform standard CRUD operations, but you can monitor the health of your Elastic cluster programmatically, back it up, or make changes to it. Some of these operations are done through "namespaced" commands, which this package happily supports.

To grab statistics for an index:

$stats = Elasticsearch::indices()->stats(['index' => 'my_index']);
$stats = Elasticsearch::nodes()->stats();
$stats = Elasticsearch::cluster()->stats();

To create and restore snapshots (read the Elastic docs about creating repository paths and plugins first):

$response = Elasticsearch::snapshots()->create($params);
$response = Elasticsearch::snapshots()->restore($params);

To delete whole indices (be careful!):

$response = Elasticsearch::indices()->delete(['index' => 'my_index']);

Please remember that this package is a thin wrapper around a large number of very sophisticated and well-documented Elastic features. Information about those features and the methods and parameters used to call them can be found in the Elastic documentation. Help with using them is available via the Elastic forums and on sites like Stack Overflow.

Console commands

This package also provides some useful console commands.

Check if an index exists:

php artisan laravel-elasticsearch:utils:index-exists <your_elasticsearch_index_name>

Create an index:

php artisan laravel-elasticsearch:utils:index-create <your_elasticsearch_index_name>

Delete an index:

php artisan laravel-elasticsearch:utils:index-delete <your_elasticsearch_index_name>

Create or update index mapping: Note: The index mapping file must contain a valid JSON mapping definition as Elasticsearch expects, for example:

{
    "body": {
        "_source": {
            "enabled": true
        },
        "properties": {
            "id": {
                "type": "keyword"
            },
            "property_1": {
                "type": "text"
            },
            "property_2": {
                "type": "text"
            }
        }
    }
}
php artisan laravel-elasticsearch:utils:index-create-or-update-mapping <your_elasticsearch_index_name> <json_mapping_absolute_file_path>

Creates an alias:

php artisan laravel-elasticsearch:utils:alias-create <your_elasticsearch_index_name> <your_elasticsearch_alias_name>

Remove index from an alias:

php artisan laravel-elasticsearch:utils:alias-remove-index <your_elasticsearch_index_name> <your_elasticsearch_alias_name>

Switch index on alias (useful for zero-downtime release of the new index):

php artisan laravel-elasticsearch:utils:alias-switch-index <your_NEW_elasticsearch_index_name> <your_OLD_elasticsearch_index_name> <your_elasticsearch_alias_name>

Bugs, Suggestions, Contributions and Support

Thanks to everyone who has contributed to this project!

Please use Github for reporting bugs, and making comments or suggestions.

See CONTRIBUTING.md for how to contribute changes.

Copyright and License

laravel-elasticsearch was written thanks to Colin Viebrock and is released under the MIT License. It is being maintained and developed by MailerLite

Copyright (c) 2026 MailerLite