PackageTrack
Sign in Get early access

pdphilip/elasticsearch

An Elasticsearch implementation of Laravel's Eloquent ORM

v5.7.1 485K downloads/mo #4408 most downloaded on Packagist source

What this package is like to depend on

Last release 3 days ago

20 Aug 2026

Release timing varies

gaps range from 8 days to 3 months

Rarely documented

notes for 21 of 115 stable releases

Nothing withdrawn

no release was ever pulled

4 years old

117 releases · first in 2022

16 releases in the last 12 months

see the full history below

Release timeline

116 releases · Mar 2022 to Aug 2026
2023 2024 2025 2026
Release Pre-release

Releases

latest 60 of 117
  1. v5.7.1 20 Aug 2026
    Release notes

    This release is compatible with Laravel 11, 12 & 13, and with Elasticsearch 8 & 9

    Added

    • Elasticsearch 9 support - the full suite runs green against ES 8.18 and 9.5, and CI now tests both on every push. No code changes were needed: the ^8.17 client talks to both server lines.
    • ElasticCollection::hasQueryMeta() - whether a collection carries the meta of the query that built it. False for the collections Eloquent builds on its own: newCollection(), hydrate(), and anything derived through map(), filter() or values().

    Fixed

    • cursor() returns a LazyCollection - matching Laravel's own builders, so cursor()->chunk(), ->map() and ->filter() work instead of fataling with Call to undefined method Generator::chunk(). Found and fixed by @BobbyBorisov in laravel-opensearch#28
    • cursor() crashed on a fresh connection - Processor::getRawResponse() dereferenced null when a cursor was the first query on its connection (Call to a member function asArray() on null)
    • paginate() lost its query meta when nothing matched - Laravel skips the query entirely once the count comes back as zero, so an empty page arrived as a bare collection and getQueryMeta() on it threw Method Illuminate\Database\Eloquent\Collection::getQueryMeta does not exist. The count query's meta is now carried onto the empty page: getTotalHits() reports 0, and it still honours withTrackTotalHits() for indices past the 10k window
    • Meta getters fataled on collections Eloquent built itself - ElasticCollection::$meta was a typed property that nothing initialised, so getQueryMeta(), getTook(), getDsl() and the rest threw Typed property ElasticCollection::$meta must not be accessed before initialization on any collection that did not come from a query. They now fall back to an empty QueryMeta, which reports its unknowns as -1. Note that nullsafe could not guard this: the error came from the property access, so $collection?->getQueryMeta() fataled too
    • Query\Builder::get() could hand a null MetaDTO to setQueryMeta() - it read the $metaTransfer property directly instead of the accessor that initialises it

    Changed

    • cursor() returns LazyCollection instead of Generator. foreach is unaffected; anything type-hinting Generator or Iterator needs updating
    • A cursor is re-iterable - a second pass opens a fresh scroll instead of throwing Cannot rewind a generator
    • Query\Builder::getMetaTransfer() (internal) returns MetaDTO instead of ?MetaDTO - it initialises on demand and never actually returned null

    Laravel 11 notice: three advisories now cover the whole 11.x branch with no 11.x release that clears them, and Composer 2.9+ blocks advisory-affected versions while resolving. On Laravel 11, composer require and composer update will refuse to install anything, this package included. composer install from a lock file still works. composer config policy.advisories.block false lifts it; upgrading to 12 or 13 is the real fix.

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.7.0...v5.7.1

    Open source →
  2. v5.7.0 24 May 2026
    Release notes

    This release is compatible with Laravel 11, 12 & 13

    Added

    • whereNestedFieldExists($path) (docs) - explicit, zero-overhead check for "this nested path has at least one document." Emits the idiomatic nested + exists form directly, no closure required. Variants: whereNotNestedFieldExists, orWhereNestedFieldExists, orWhereNotNestedFieldExists.
    • whereFieldExists($field) (docs) - properly named alias for the Elasticsearch exists query. Variants: whereNotFieldExists, orWhereFieldExists, orWhereNotFieldExists.
    • nestedQuery($column) (docs) - returns a pre-configured Builder you can build up across conditionals and functions, then pass straight to whereNestedObject(). The closure form still works for simple cases; this is the escape hatch for programmatic composition.
    • whereNestedObject() now accepts a pre-built Builder (from nestedQuery()) in addition to a Closure or raw DSL string. Invalid input now throws BuilderException instead of silently being stored.

    Changed

    • Exists queries on nested-mapped fields auto-wrap in nested (docs) - whereFieldExists('comments.country'), whereNotNull('comments.country'), and whereNull('comments.country') now emit the idiomatic nested { path: comments, query: { exists: ... } } form when the target field lives under a nested path. Detection only fires for dotted field names - bare-field calls (whereNotNull('title')) pay no overhead.
    • IDE/PHPDoc improvements - find, first, firstOrCreate now return static (not the abstract base Model), so subclass property hints resolve correctly. Collection-returning methods (get, rawSearch, distinct, bulkDistinct) annotated as array<int, static> so foreach typing works in PhpStorm. ElasticCollection template hygiene tightened (FQN parent in @extends, dropped name-colliding use Model as TModel alias).

    Deprecated

    • whereTermExists family - replaced by whereFieldExists. The Term prefix was historical (the underlying ES query isn't term-related) and the old name avoided collision with Laravel's base whereExists(Closure). Old methods still work; will be removed in v6:
      • whereTermExistswhereFieldExists
      • whereNotTermExistswhereNotFieldExists
      • orWhereTermExistsorWhereFieldExists
      • orWhereNotTermsExistsorWhereNotFieldExists (also fixes the typo'd plural "Terms")

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.6.1...v5.7.0

    Open source →
  3. v5.6.1 06 Apr 2026
    Release notes

    Future-proofing note: After GitHub incorrectly shadow-banned my account (since reinstated with no explanation beyond "it shouldn't happen again"), all packages are now mirrored to GitLab. GitHub remains the home for issues, PRs, and community collaboration, but Packagist downloads exclusively from GitLab to ensure uninterrupted access to releases regardless of GitHub's actions.

    This release is compatible with Laravel 11, 12 & 13

    Fixed

    • Laravel 13.3 compatibility - newCollection() override on base Model to prevent HasCollection trait from attempting to instantiate the abstract parent class (Cannot instantiate abstract class error introduced in Laravel 13.3's new resolveCollectionFromAttribute grandchild resolution)
    • QueryException crash on Undefined array key "error" when Elasticsearch returns responses without the expected error.type structure (e.g. malformed or non-standard error payloads)

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.6.0...v5.6.1

    Open source →
  4. v5.6.0 24 Mar 2026
    Release notes

    This release is compatible with Laravel 11, 12 & 13

    Added

    • Laravel 13 support
    • Symfony 8 support (via Laravel 13)
    • Composer test scripts for per-version testing: composer test:l11, composer test:l12, composer test:l13, composer test:all

    Changed

    • Dropped Laravel 10 support (EOL)
    • pdphilip/omniterm bumped to ^3.0
    • Connection::select() signature updated with $fetchUsing parameter (Laravel 13 compatibility)
    • CI matrix updated: PHP 8.3/8.4, Laravel 11/12/13

    Refactored

    • Collapsed Laravel version compatibility layer from 12 files (4 dispatchers + 4 v11 traits + 4 v12 traits) into 4 self-contained traits. Version checks now happen inside each method with spread operators for different constructor signatures - no more file-level conditional trait loading. Removed phpstan bootstrap class_alias hacks that were needed for the old pattern.

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.5.3...v5.6.0

    Open source →
  5. v5.5.3 20 Mar 2026
    Release notes

    Fixed

    • distinct(), bulkDistinct(), and groupBy() now work on nested fields (e.g., distinct('tags.key', true)). Previously these returned empty results because the compiled DSL lacked the required nested aggregation wrapper. The package now auto-detects nested mappings and wraps aggregations accordingly - no changes needed in userland code.
    • When whereNestedObject() is combined with distinct() on the same nested path, the nested filter is injected inside the aggregation context so that only matching sub-documents are aggregated.

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.5.2...v5.5.3

    Open source →
  6. v5.5.2 16 Mar 2026
    Release notes

    Improved

    • elastic:re-index mapping analysis now includes settings for analyzers, tokenizers, char filters, filters, and normalizers.

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.5.1...v5.5.2

    Open source →
  7. v5.5.1 16 Mar 2026
    Release notes

    Added

    • Schema::compileMapping() - compile a Blueprint callback into its resulting ES mapping structure without creating the index. Useful for debugging and previewing what mappingDefinition() will produce.
    • Grammar::compileMapping() - public access to the Blueprint-to-properties compilation pipeline.

    Fixed

    • elastic:re-index now correctly detects nested field mappings (e.g., nested('tags')->properties(...)) including their sub-fields and keyword sub-field changes.

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.5.0...v5.5.1

    Open source →
  8. v5.5.0 15 Mar 2026
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    What's new in v5.5

    New features

    Automated Re-indexing Command

    New elastic:re-index command that automates the entire re-indexing process when your field mappings change. Pass a model name and the command handles the rest - creating a temp index, copying data, verifying counts, swapping, and cleaning up across 9 interactive phases with confirmation prompts between each step. - Docs

    php artisan elastic:re-index UserLog
    php artisan elastic:re-index "App\Models\ES\UserLog"
    

    Features include:

    • Smart mapping analysis that detects type mismatches and sub-field changes (e.g., adding hasKeyword: true)
    • Resume capability - interrupted runs pick up where they left off
    • Configurable tolerance and retry settings
    • --force flag to skip all confirmation prompts

    Model Scaffolding Command

    New elastic:make command to scaffold Elasticsearch models with the correct base class, connection, and a starter mappingDefinition(). - Docs

    php artisan elastic:make UserLog
    php artisan elastic:make ES/UserLog
    

    Mapping Definition on Models

    Define your index field mappings directly on the model by overriding mappingDefinition(). Uses the same Blueprint syntax as migrations. Powers the elastic:re-index command's mapping analysis. - Docs

    public static function mappingDefinition(Blueprint $index): void
    {
        $index->keyword('status');
        $index->text('title', hasKeyword: true);
        $index->geoPoint('location');
    }
    

    Artisan Commands Reference

    All five Artisan commands (elastic:status, elastic:indices, elastic:show, elastic:make, elastic:re-index) are now documented on a dedicated page. - Docs

    Fixed

    • whereNestedObject() and filterNested() no longer leak parentField into the parent query builder. The nested path was being set on $this instead of the sub-query, causing it to persist across subsequent queries on the same builder.

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.4.1...v5.5.0

    Open source →
  9. v5.4.1 23 Feb 2026
    Release notes

    Fixed

    • _id no longer leaks into serialized output (toArray(), toJson()). The internal _id metadata field was being exposed alongside id, resulting in duplicate ID fields in model serialization.
    Open source →
  10. v5.4.0 21 Feb 2026
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    What's new in v5.4

    New features

    Auto-Create Index

    When a model queries an index that doesn't exist yet, the index is created automatically instead of throwing index_not_found_exception. Matches Elasticsearch's own auto-create behavior for writes, extended to reads.

    // No migration needed - index is created on first query
    $products = Product::where('status', 'active')->get(); // returns empty collection
    

    Controlled via options.auto_create_index config (default: true). - Docs

    Why: New models shouldn't crash before the first write. Elasticsearch already auto-creates on insert; this extends the same behavior to reads.

    Artisan Commands

    First-class CLI tools for managing your Elasticsearch connection and indices:

    • php artisan elastic:status - Connection health check with cluster info and license details
    • php artisan elastic:indices - List all indices with health, doc count, and store size
    • php artisan elastic:show {index} - Inspect an index: overview, mappings, settings, and analysis config
    php artisan elastic:status
    php artisan elastic:indices --all
    php artisan elastic:show products
    

    All commands support --connection= for non-default connections.

    Why: Until now, inspecting your Elasticsearch setup meant leaving Laravel for curl or Kibana. These commands bring that visibility into Artisan where it belongs.

    Upsert

    New upsert() method matching Laravel's native signature. Insert or update records by unique key in a single bulk operation. - Docs

    Product::upsert(
        [
            ['sku' => 'ABC', 'name' => 'Widget', 'price' => 10],
            ['sku' => 'DEF', 'name' => 'Gadget', 'price' => 20],
        ],
        ['sku'],           // unique key
        ['name', 'price']  // columns to update if exists
    );
    

    Supports single documents, batch operations, and composite unique keys.

    Why: Elasticsearch has no native upsert-by-field. This queries for existing documents first, then issues a single bulk request mixing index and update actions.

    Time-Ordered IDs

    New GeneratesTimeOrderedIds trait for sortable, chronologically-ordered IDs. 20 characters, URL-safe, lexicographic sort matches creation order across processes. - Docs

    use PDPhilip\Elasticsearch\Eloquent\GeneratesTimeOrderedIds;
    
    class TrackingEvent extends Model
    {
        use GeneratesTimeOrderedIds;
    }
    
    $event->id;                    // "0B3kF5XRABCDE_fghijk"
    $event->getRecordTimestamp();  // 1771160093773 (ms)
    $event->getRecordDate();       // Carbon instance
    

    Safe for mixed datasets; returns null for pre-existing IDs not generated by this trait.

    Why: When you need IDs that sort chronologically across multiple processes/workers, ideal for high-volume event tracking and time-sequenced analytics.

    Changed

    • Refactored Query Builder into focused concerns: BuildsAggregations, BuildsSearchQueries, BuildsFieldQueries, BuildsGeoQueries, BuildsNestedQueries, HandlesScripts, ManagesPit
    • Refactored Grammar into concerns: CompilesAggregations, CompilesOrders, CompilesWheres, FieldUtilities
    • Decomposed ElasticsearchModel trait into focused traits for clarity
    • Consolidated ES PHP client usage into ElasticClient wrapper
    • Consolidated metadata handling into single MetaDTO
    • Simplified ManagesOptions parameter inference
    • Extracted addFieldQuery() dispatcher in BuildsFieldQueries to deduplicate field query methods
    • Refactored Relations for readability: early returns, named variables, simplified loops
    • Schema Builder: added getIndexes(), getForeignKeys(), getViews() for Laravel compatibility
    • CI updated to Elasticsearch 8.18.0
    • Test suite expanded from 379 to 422 tests (2,548 assertions), all passing

    Fixed

    • id is now always present in serialized model output (toArray(), toJson())
    • _id is no longer exposed in serialized output (internal metadata stays internal)
    • Removed dead debug code from Connection.php

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.3.0...v5.4.0

    Open source →
  11. v5.3.0 20 Jan 2026
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    New features

    Distinct with Relations

    distinct() queries now return ElasticCollections;

    If a model relation exists and the aggregation is done on the foreign key, you can load the related model

    UserLog::where('created_at', '>=', Carbon::now()->subDays(30))
        ->with('user')
        ->orderByDesc('_count')
        ->select('user_id')
        ->distinct(true);
    
    
    

    Why: You can now treat distinct aggregations like real Eloquent results, including relationships.

    Bulk Distinct Queries

    New query method bulkDistinct(array $fields, $includeDocCount = false) - Docs

    Run multiple distinct aggregations in parallel within a single Elasticsearch query.

    $top3 = UserSession::where('created_at', '>=', Carbon::now()->subDays(30))
        ->limit(3)
        ->bulkDistinct(['country', 'device', 'browser_name'], true);
    
    

    Why: Massive performance gains vs running sequential distinct queries.

    Group By Ranges

    groupByRanges() performs a range aggregation on the specified field. - Docs

    groupByRanges()->get() - return bucketed results - Docs

    groupByRanges()->agg() - apply metric aggregations per bucket -Docs

    Group By Date Ranges

    groupByDateRanges() performs a date range aggregation on the specified field. - Docs

    groupByDateRanges()->get() - bucketed date ranges

    groupByDateRanges()->agg() - metrics per date bucket

    Model Meta Accessor

    New model method getMetaValue($key) - Docs

    Convenience method to get a specific meta value from the model instance.

    $product = Product::where('color', 'green')->first();
    $score = $product->getMetaValue('score');
    
    

    Bucket Values in Meta

    When a bucketed query is executed, the raw bucket data is now stored in model meta. -Docs

    $products = Product::distinct('price');
    $buckets = $products->map(function ($product) {
        return $product->getMetaValue('bucket');
    });
    
    

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.2.0...v5.3.0

    Open source →
  12. v5.2.0 24 Oct 2025
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    New Feature: Query String Queries

    This release introduces Query String Queries, bringing full Elasticsearch query_string syntax support directly into your Eloquent-style queries.

    • Method: searchQueryString(query, $fields = null, $options = []) and related methods (orSearchQueryString, searchNotQueryString, etc.)
    • Supports all query_string features - logical operators, wildcards, fuzziness, ranges, regex, boosting, field scoping, and more
    • Includes a dedicated QueryStringOptions class for fluent option configuration or array-based parameters
    • See Tests
    • Full documentation

    Example:

    Product::searchQueryString('status:(active OR pending) name:(full text search)^2')->get();
    Product::searchQueryString('price:[5 TO 19}')->get();
    
    // vanilla optional, +pizza required, -ice forbidden
    Product::searchQueryString('vanilla +pizza -ice', function (QueryStringOptions $options) {
        $options->type('cross_fields')->fuzziness(2);
    })->get();
    
    //etc
    
    
    

    Ordering enhancement: unmapped_type

    • You can now add an unmapped_type flag to your ordering query #88
    Product::query()->orderBy('name', 'desc', ['unmapped_type' => 'keyword'])->get();
    
    
    

    Bugfix

    • Fixed issue where limit values were being reset on bucket aggregations #84

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.1.0...v5.2.0

    Open source →
  13. v5.1.0 20 Aug 2025
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    1. New feature, withTrackTotalHits(bool|int|null $val = true)

    Appends the track_total_hits parameter to the DSL query, setting value to true will count all the hits embedded in the query meta not capping to Elasticsearch default of 10k hits

    $products = Product::limit(5)->withTrackTotalHits(true)->get();
    $totalHits = $products->getQueryMeta()->getTotalHits();
    
    
    
    

    This can be set by default for all queries by updating the connection config in database.php:

    'elasticsearch' => [
        'driver' => 'elasticsearch',
        .....
        'options' => [
            'track_total_hits' => env('ES_TRACK_TOTAL_HITS', null),
            ....
        ],
    ],
    
    
    
    

    2. New feature, createOrFail(array $attributes)

    By default, when using create($attributes) where $attributes has an id that exists, the operation will upsert. createOrFail will throw a BulkInsertQueryException with status code 409 if the id exists

    Product::createOrFail([
        'id' => 'some-existing-id',
        'name' => 'Blender',
        'price' => 30,
    ]);
    
    
    
    

    3. New feature withRefresh(bool|string $refresh)

    By default, inserting documents will wait for the shards to refresh, ie: withRefresh(true), you can set the refresh flag with the following (as per ES docs):

    • true (default) Refresh the relevant primary and replica shards (not the whole index) immediately after the operation occurs, so that the updated document appears in search results immediately.
    • wait_for Wait for the changes made by the request to be made visible by a refresh before replying. This doesn’t force an immediate refresh, rather, it waits for a refresh to happen.
    • false Take no refresh-related actions. The changes made by this request will be made visible at some point after the request returns.
    Product::withRefresh('wait_for')->create([
        'name' => 'Blender',
        'price' => 30,
    ]);
    
    
    
    

    PRS

    • Add withTrackTotalHits method to Builder class to add track_total_hits by @caufab in https://github.com/pdphilip/laravel-elasticsearch/pull/76
    • feat(query): add op_type=create support and dedupe helpers by @abkrim in https://github.com/pdphilip/laravel-elasticsearch/pull/79

    Bugfix

    • Laravel ^12.23 Compatibility - close #81

    New Contributors

    • @caufab made their first contribution in https://github.com/pdphilip/laravel-elasticsearch/pull/76

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.0.7...v5.1.0

    Open source →
  14. v5.0.7 13 Jul 2025
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    What's Changed

    • Connection bug fix by @pdphilip in https://github.com/pdphilip/laravel-elasticsearch/pull/75 - close #70

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.0.6...v5.0.7

    Open source →
  15. v5.0.6 04 Jun 2025
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    What's Changed

    • Bug fix: Chunking $count value fixed for setting query limit correctly, via #68

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.0.5...v5.0.6

    Open source →
  16. v5.0.5 19 May 2025
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    What's Changed

    • Merging in bug fixes by @use-the-fork in https://github.com/pdphilip/laravel-elasticsearch/pull/65
    • Updated outstanding tests
    • Fixed bug in relationshas() method

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.0.4...v5.0.5

    Open source →
  17. v5.0.4 13 Apr 2025
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    What's changed

    • Connection disconnect() resets connection - removing connection is unnecessary in the context of Elasticsearch. Issue #64
    • Added getTotalHits() helper method from query meta
    • Bug fix: searchFuzzy() parses options as a closure
    • Minor code reorganising

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.0.3...v5.0.4

    Open source →
  18. v5.0.3 28 Mar 2025
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    What's changed

    • Bug fix: Internal model attribute meta renamed to _meta to avoid the issue where a model could have a field called meta
    • Bug fix: highlight() passed without fields did not highlight all hits
    • Bug fix: Hybrid BelongsTo in some SQL cases used ES connection
    • Bug fix: orderBy('_score') was not parsing correctly
    • Bug fix: Edge case where a string value was being seen as callable

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.0.2...v5.0.3

    Open source →
  19. v5.0.2 28 Mar 2025
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    What's changed

    1. New feature, bulkInsert()

    bulkInsert() is identical to insert() but will continue on errors and return an array of the results.

    People::bulkInsert([
        [
            'id' => '_edo3ZUBnJmuNNwymfhJ', // Will update (if id exists)
            'name' => 'Jane Doe',
            'status' => 1,
        ],
        [
            'name' => 'John Doe',  // Will Create
            'status' => 2,
        ],
        [
            'name' => 'John Dope',
            'status' => 3,
            'created_at' => 'xxxxxx', // Will fail
        ],
    ]);
    
    
    
    
    
    
    
    
    

    Returns:

    {
      "hasErrors": true,
      "total": 3,
      "took": 0,
      "success": 2,
      "created": 1,
      "modified": 1,
      "failed": 1,
      "errors": [
        {
          "id": "Y-dp3ZUBnJmuNNwy7vkF",
          "type": "document_parsing_exception",
          "reason": "[1:45] failed to parse field [created_at] of type [date] in document with id 'Y-dp3ZUBnJmuNNwy7vkF'. Preview of field's value: 'xxxxxx'"
        }
      ]
    }
    
    
    
    
    
    
    
    

    2. Bug fix: distinct() aggregation now appends searchAfter key in meta

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.0.1...v5.0.2

    Open source →
  20. v5.0.1 28 Mar 2025
    Release notes

    This release is compatible with Laravel 10, 11 & 12

    What's changed

    • Updated model docs for comprehensive IDE support when building queries
    • Added orderByNestedDesc()
    • Removed & replaced compatibility-loader that depended on class_alias to set the correct traits for the given Laravel version

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v5.0.0...v5.0.1

    Open source →
  21. v5.0.0 26 Mar 2025
    Release notes

    We’re excited to announce v5 of the laravel-elasticsearch package - compatible with Laravel 10, 11, and 12.

    Acknowledgement

    V5 is the brainchild of @use-the-fork and is a near-complete rewrite of the package; packed with powerful new features, deep integration with Elasticsearch’s full capabilities, and a much tighter alignment with Laravel’s Eloquent. It lays a solid, future-proof foundation for everything that comes next.

    Upgrading

    "pdphilip/elasticsearch": "^5",
    
    
    
    
    
    
    
    

    Breaking Changes

    1. Connection

    • Index Prefix Handling The ES_INDEX_PREFIX no longer auto-appends an underscore (_). Old behavior: ES_INDEX_PREFIX=my_prefixmy_prefix_ New: set explicitly if needed → ES_INDEX_PREFIX=my_prefix_

    2. Models

    • Model ID Field $model->_id is deprecated. Use $model->id instead. If your model had a separate id field, you must rename it.

    • Default Limit Constant MAX_SIZE constant is removed. Use $defaultLimit property:

      use PDPhilip\Elasticsearch\Eloquent\Model;
      
      class Product extends Model
      {
          protected $defaultLimit = 10000;
          protected $connection = 'elasticsearch';
      }
      
      
      
      
      
      
      
      

    3. Queries

    • where() Behavior Changed

      Now uses term query instead of match.

      // Old:
      Product::where('name', 'John')->get(); // match query
      // New:
      Product::whereMatch('name', 'John')->get(); // match query
      Product::where('name', 'John')->get();      // term query
      
      
      
      
      
      
      
      
    • orderByRandom() Removed

      Replace with functionScore() Docs

    • Full-text Search Options Updated Methods like asFuzzy(), setMinShouldMatch(), setBoost() removed. Use callback-based SearchOptions instead:

      Product::searchTerm('espresso time', function (SearchOptions $options) {
            $options->searchFuzzy();
          $options->boost(2);
            $options->minimumShouldMatch(2);
      })->get();
      
      
      
      
      
      
      
      
    • Legacy Search Methods Removed All {xx}->search() methods been removed. Use {multi_match}->get() instead.

    4. Distinct & GroupBy

    • distinct() and groupBy() behavior updated. Docs

      Review queries using them and refactor accordingly.

    5. Schema

    • IndexBlueprint and AnalyzerBlueprint has been removed and replaced with a single Blueprint class

      -   use PDPhilip\Elasticsearch\Schema\IndexBlueprint;
      -   use PDPhilip\Elasticsearch\Schema\AnalyzerBlueprint;
      use PDPhilip\Elasticsearch\Schema\Blueprint;
      
      
      
      
      
      
      
      
    • Schema::hasIndex has been removed. Use Schema::hasTable or Schema::indexExists instead.

    • geo($field) field property has been replaced with geoPoint($field)

    • {field}->index($bool) field property has been replaced with {field}->indexField($bool);

    • alias() field type has been removed. Use aliasField() instead.

    • settings() method has been replaced with withSetting()

    • map() method has been replaced with withMapping()

    • analyzer() method has been replaced with addAnalyzer()

    • tokenizer() method has been replaced with addTokenizer()

    • charFilter() method has been replaced with addCharFilter()

    • filter() method has been replaced with addFilter()

    6. Dynamic Indices

    • Dynamic indices are now managed by the DynamicIndex trait. upgrade guide

    New features

    1. Laravel-Generated IDs

    • You can now generate Elasticsearch ids in Laravel Docs

    2. Fluent query options as a callback

    • All clauses in the query builder now accept an optional callback of Elasticsearch options to be applied to the clause. Docs

    3. Belongs to Many Relationships

    • Belongs to many relationships are now supported. Docs

    4. New queries

    5. New aggregations

    • Boxplot Aggregations Docs
    • Stats Aggregations Docs
    • Extended Stats Aggregations - Docs
    • Cardinality Aggregations - Docs
    • Median Absolute Deviation Aggregations - Docs
    • Percentiles Aggregations - Docs
    • String Stats Aggregations - Docs

    6. Migratons: Add Normalizer

    • Normalizers can now be defined in migrations. Docs

    7. Direct Access to Elasticsearch PHP client

    Connection::on('elasticsearch')->elastic()->{clientMethod}();
    
    
    
    
    
    
    
    

    What's Changed

    • V5.0.0 by @use-the-fork in https://github.com/pdphilip/laravel-elasticsearch/pull/54
    • Small Bug Fixes found in RC1 by @use-the-fork in https://github.com/pdphilip/laravel-elasticsearch/pull/60

    Full Changelog: https://github.com/pdphilip/laravel-elasticsearch/compare/v4.5.3...v5.0.0

    Open source →
  22. v5.0.0-RC2 17 Mar 2025 pre-release

    Nothing published for this version

  23. v5.0.0-RC1 13 Mar 2025 pre-release

    Nothing published for this version

  24. v4.5.3 20 Mar 2025

    Nothing published for this version

  25. v4.5.2 19 Mar 2025

    Nothing published for this version

  26. v4.5.1 12 Mar 2025

    Nothing published for this version

  27. v4.5.0 17 Oct 2024

    Nothing published for this version

  28. v4.4.1 04 Oct 2024

    Nothing published for this version

  29. v4.4.0 02 Oct 2024

    Nothing published for this version

  30. v4.3.0 23 Sep 2024

    Nothing published for this version

  31. v4.2.0 16 Sep 2024

    Nothing published for this version

  32. v4.1.1 06 Sep 2024

    Nothing published for this version

  33. v4.1.0 04 Sep 2024

    Nothing published for this version

  34. v4.0.4 17 Aug 2024

    Nothing published for this version

  35. v4.0.3 31 Jul 2024

    Nothing published for this version

  36. v4.0.2 06 Jun 2024

    Nothing published for this version

  37. v4.0.1 29 Apr 2024

    Nothing published for this version

  38. v4.0.0 29 Apr 2024

    Nothing published for this version

  39. v3.11.0 01 Apr 2024

    Nothing published for this version

  40. v3.10.0 25 Mar 2024

    Nothing published for this version

  41. v3.9.4 17 Aug 2024

    Nothing published for this version

  42. v3.9.3 31 Jul 2024

    Nothing published for this version

  43. v3.9.2 06 Jun 2024

    Nothing published for this version

  44. v3.9.1 29 Apr 2024

    Nothing published for this version

  45. v3.9.0 25 Mar 2024

    Nothing published for this version

  46. v3.8.4 17 Aug 2024

    Nothing published for this version

  47. v3.8.3 31 Jul 2024

    Nothing published for this version

  48. v3.8.2 06 Jun 2024

    Nothing published for this version

  49. v3.8.1 29 Apr 2024

    Nothing published for this version

  50. v3.8.0 25 Mar 2024

    Nothing published for this version

  51. v2.10.7 14 Mar 2024

    Nothing published for this version

  52. v2.10.6 29 Feb 2024

    Nothing published for this version

  53. v2.10.5 27 Feb 2024

    Nothing published for this version

  54. v2.10.4 10 Jan 2024

    Nothing published for this version

  55. v2.10.3 14 Nov 2023

    Nothing published for this version

  56. v2.10.2 03 Nov 2023

    Nothing published for this version

  57. v2.10.1 20 Oct 2023

    Nothing published for this version

  58. v2.10.0 18 Sep 2023

    Nothing published for this version

  59. v2.9.9 29 Feb 2024

    Nothing published for this version

  60. v2.9.8 28 Feb 2024

    Nothing published for this version

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive