Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Elasticlens Laravel Package

pdphilip/elasticlens

ElasticLens brings Elasticsearch power to Laravel models with Eloquent-style queries. Define your own index models, mappings, and schema—no black box. Run phrase/term searches, filters, embedded fields, geo distance sorting, and pagination with fluent, readable APIs.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing the package via Composer and publishing its config:

composer require pdphilip/elasticlens  
php artisan lens:install  
php artisan migrate  

Then configure config/database.php with an elasticsearch connection (per the README). Next, enable indexing on your model using the Indexable trait and create a corresponding Indexed{Model} class (e.g., IndexedUser). That’s enough for basic syncing and searching via:

User::viaIndex()->searchTerm('coffee')->get(); // now returns `User[]` directly  

First read the Indexing your Base-Model docs section and run php artisan lens:make ModelName to scaffold the Indexed* model.

Implementation Patterns

  • Zero-Config Indexing: Add use Indexable; to your Eloquent model and create App\Models\Indexes\Indexed{Model}. Automatic sync happens on create/update/delete.
  • Search with Eloquent Fluency: Use familiar Eloquent syntax extended with Elasticsearch-specific methods:
    User::viaIndex()  
        ->where('status', 'active')  
        ->searchPhrase('java developer')  
        ->orderByDesc('created_at')  
        ->get(); // returns `User[]` directly (no `->getBase()` needed)  
    
  • Embedded Relationships: Define relationships (e.g., posts, settings) in the field map to denormalize nested data — crucial for avoiding joins at search time.
  • Index Migration Strategy: Use mapIndexBuild() to define schema requirements and enforce index versions via lens:migrate/lens:rebuild.
  • CLI Monitoring: Leverage artisan commands like lens:health, lens:status, lens:rebuild-index User to inspect and maintain indexes in CI/CD or ops workflows.
  • Hybrid Queries: Mix Elasticsearch search methods (searchTerm, filterGeoPoint, whereNestedObject) alongside standard Laravel query builders — ideal for advanced filtering (e.g., geo + status + time window).
  • Conditional Indexing: Use excludeIndex() in your Indexed{Model} to prevent specific records from being indexed (e.g., ->where('is_draft', true)).
  • Soft Delete Support: Enable soft-delete sync automatically via use HasIndexableSoftDeletes; on the index model (or configure globally in config/elasticlens.php).

Gotchas and Tips

  • Return Type Shift (v4): viaIndex()->get() now returns base models (e.g., User[]) by default. Use ->getIndex() or ->paginateIndex() if you explicitly need IndexedUser[] instances.
  • getBase() is Deprecated for Default Usage: While still functional, ->getBase() is no longer necessary. Remove it unless you intentionally need index model access.
  • Index-Model ≠ Base-Model (Still Relevant): Though get() returns base models, intermediate objects (e.g., builders, scopes) still reference index models. Be cautious with type-hinting and serialization.
  • Field Mapping Overrides: Default mapping may not preserve types (e.g., dates, booleans). Use FieldMap::make() in your Indexed* model’s buildIndex() method to explicitly define field types and analyzers.
  • Nested Objects Require Mapping: Search on nested relationships (user_logs) won’t work unless declared in the fieldMap as nested types.
  • Observing the Wrong Models: By default, Indexable watches the base model. If using custom observers or scaling across many models, register specific classes in config/elasticlens.php’s observed_models.
  • Rebuilds Without Downtime: Use lens:migrate to diff and migrate indexes incrementally — avoid lens:rebuild-index in production unless necessary.
  • Eager Loading Limitation: Embedded relationships don’t eager-load related data like Eloquent relations — they’re static at indexing time. For dynamic/expensive joins, prefer filtering with embedded fields instead of linking.
  • Highlighting + Snippets: Use withHighlights() to get matches, but remember to include the field in fieldMap and request _source for full content.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport