### Run ElasticLens Install Command Source: https://github.com/pdphilip/elasticlens/blob/main/CHANGELOG.md After installation, run the Artisan command to complete the setup. ```bash php artisan lens:install ``` -------------------------------- ### Publish Config and Create Indexes Source: https://github.com/pdphilip/elasticlens/blob/main/README.md After installing ElasticLens, publish the configuration file using `lens:install` and create the necessary database indexes for build state and migration logs using `php artisan migrate`. ```bash php artisan lens:install # Publish config ``` ```bash php artisan migrate # Create build state + migration log indexes ``` -------------------------------- ### Install ElasticLens via Composer Source: https://github.com/pdphilip/elasticlens/blob/main/CHANGELOG.md Use Composer to require the ElasticLens package. ```bash composer require pdphilip/elasticlens ``` -------------------------------- ### Various Search Query Examples Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Demonstrates different ways to query your Elasticsearch index using ElasticLens, including basic searches, fuzzy matching, and regular expression filtering. ```php // Quick search across all fields User::search('vinyl collecting'); // Full Elasticsearch query builder. Go nuts. User::viaIndex()->searchTerm('vinyl')->where('state', 'active')->get(); User::viaIndex()->searchFuzzy('elsticsearsh')->get(); // can't even spell it? no problem User::viaIndex()->whereRegex('hobby', 'sw(im|itch)')->paginate(10); ``` -------------------------------- ### Get Query for Failed Build Errors Source: https://github.com/pdphilip/elasticlens/blob/main/CHANGELOG.md Use this helper to retrieve a query for failed build errors of a specific index model. Ensure the `IndexableBuild` class is imported. ```php use Pdphilip\ElasticLens\Models\IndexableBuild; $buildErrors = IndexableBuild::buildErrorsQuery(IndexedUser::class)->get(); ``` -------------------------------- ### Get First Result as Index Model Source: https://context7.com/pdphilip/elasticlens/llms.txt Retrieve the first matching record as an index model. Use the `firstIndex()` method when you need to work with the index-specific model instance. ```php where('email', 'john@example.com')->firstIndex(); ``` -------------------------------- ### Explicitly Get Base Models from Index Query Source: https://context7.com/pdphilip/elasticlens/llms.txt Retrieve results as base Eloquent models even when starting from an index model query. Use the `getBase()` method for this conversion. ```php searchTerm('developer') ->getBase(); ``` -------------------------------- ### Define Elasticsearch Mapping with Blueprint Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Define your Elasticsearch mapping using a Blueprint closure, similar to database migrations. This example shows text, keyword, and nested field mappings. ```php public function migrationMap(): callable { return function (Blueprint $index) { $index->text('first_name'); $index->keyword('first_name'); $index->text('email'); $index->keyword('email'); $index->keyword('state'); $index->nested('profiles'); }; } ``` -------------------------------- ### Override Global Configuration Per Index Model Source: https://context7.com/pdphilip/elasticlens/llms.txt Index models can override global configuration settings. This example shows how to override soft delete behavior, set a custom chunk size for bulk operations, and specify a migration version. ```php where('email', 'john@example.com')->first(); ``` -------------------------------- ### Explicitly Get Index Models from Index Query Source: https://context7.com/pdphilip/elasticlens/llms.txt Ensure results are returned as index models when querying from an index model. The `getIndex()` method explicitly retrieves these models. ```php searchTerm('developer') ->getIndex(); ``` -------------------------------- ### Get Elasticsearch Index Health Status Source: https://context7.com/pdphilip/elasticlens/llms.txt Retrieve the health status of the Elasticsearch index associated with the `IndexedUser` model. ```php $health = IndexedUser::lensHealth(); ``` -------------------------------- ### Explicitly Get First Result as Base Model Source: https://context7.com/pdphilip/elasticlens/llms.txt Retrieve the first matching record as a base Eloquent model when querying from an index model. The `firstBase()` method ensures the result is a base model. ```php where('email', 'john@example.com')->firstBase(); ``` -------------------------------- ### Run Index Migration Source: https://github.com/pdphilip/elasticlens/blob/main/CHANGELOG.md Use the `lens:migrate` Artisan command to perform index migrations. This command replaced the previous `lens:build` command. ```bash php artisan lens:migrate {model} ``` -------------------------------- ### Run Bulk Index Builder Source: https://github.com/pdphilip/elasticlens/blob/main/CHANGELOG.md Use the `lens:build` Artisan command to initiate the bulk index rebuilding process for a specified model. ```bash php artisan lens:build {model} ``` -------------------------------- ### View Failed Index Builds with Details Source: https://context7.com/pdphilip/elasticlens/llms.txt This command displays a paginated list of failed index builds, including detailed error messages. Useful for debugging indexing issues. ```php php artisan lens:errors User ``` -------------------------------- ### Query Index Build Information Source: https://context7.com/pdphilip/elasticlens/llms.txt Retrieve information about index builds, including the latest builds and failed builds. Also, query migration history. ```php $builds = IndexedUser::whereIndexBuilds(byLatest: true)->get(); ``` ```php $errors = IndexedUser::whereFailedIndexBuilds()->get(); ``` ```php $migrations = IndexedUser::whereMigrations()->get(); ``` -------------------------------- ### ElasticLens CLI Commands Source: https://github.com/pdphilip/elasticlens/blob/main/README.md A collection of Artisan commands for managing Elasticsearch indexes with ElasticLens. Includes status, health checks, building, migrating, and generating models. ```bash php artisan lens:status # Bird's eye view of all indexes ``` ```bash php artisan lens:health User # Deep health check for one index ``` ```bash php artisan lens:build User # Bulk rebuild all records ``` ```bash php artisan lens:migrate User # Drop, migrate, rebuild. The nuclear option. ``` ```bash php artisan lens:make Profile # Generate a new index model ``` -------------------------------- ### Run Index Migration via Artisan Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Execute the `lens:migrate` Artisan command to drop, migrate, and rebuild the index for a specified model. This is a comprehensive index update operation. ```bash php artisan lens:migrate User ``` -------------------------------- ### Simple Search with Base Models Source: https://context7.com/pdphilip/elasticlens/llms.txt Perform a basic search for a term and retrieve results as base Eloquent models. Ensure the User model is correctly set up to interact with its corresponding index. ```php searchTerm('developer')->get(); ``` -------------------------------- ### Configure Namespaces and Index Paths Source: https://github.com/pdphilip/elasticlens/blob/main/CHANGELOG.md Update the elasticlens.php config file to map models to their index namespaces and file paths for domain-driven architecture support. ```php 'namespaces' => [ 'App\Models' => 'App\Models\Indexes', ], 'index_paths' => [ 'app/Models/Indexes/' => 'App\Models\Indexes', ], ``` -------------------------------- ### Generate Index Model Artisan Command Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Use the `lens:make` Artisan command to generate an `IndexModel` for your Eloquent model. This generated model will handle indexing and synchronization. ```bash php artisan lens:make User ``` -------------------------------- ### Convert Collection of Index Models to Base Models Source: https://context7.com/pdphilip/elasticlens/llms.txt Convert an existing collection of index models into a collection of base Eloquent models using the `asBase()` method on the collection. ```php get(); $users = $indexedUsers->asBase(); ``` -------------------------------- ### Query Build Errors Programmatically Source: https://context7.com/pdphilip/elasticlens/llms.txt Retrieve and iterate over failed index build records programmatically. This allows for detailed inspection of errors, including the error message. ```php get(); foreach ($errors as $error) { echo "Model ID: {$error->model_id}, Error: {$error->state_data['msg']}"; } ``` -------------------------------- ### Paginate Results as Index Models Source: https://context7.com/pdphilip/elasticlens/llms.txt Paginate search results and receive them as index models. Use the `paginateIndex()` method for this purpose. ```php where('status', 'active') ->paginateIndex(15); ``` -------------------------------- ### Perform Basic Search with ElasticLens Source: https://context7.com/pdphilip/elasticlens/llms.txt Use the `search` method directly on the model for a quick search across all indexed fields. This is a convenient way to perform simple text searches. ```php // Quick search across all indexed fields $results = User::search('elasticsearch expert'); ``` -------------------------------- ### ElasticLens Configuration File Source: https://context7.com/pdphilip/elasticlens/llms.txt The `config/elasticlens.php` file allows customization of ElasticLens behavior, including Elasticsearch connection, queue settings, soft delete handling, watchers, and namespace mappings. ```php 'elasticsearch', // Queue for async index builds (null = sync, or 'default', 'high', etc.) 'queue' => null, // Global soft delete behavior // true: Soft-deleted models keep their index (deleted_at synced) // false: Soft-deleted models are removed from index 'index_soft_deletes' => false, // Manual watchers for models without Indexable trait 'watchers' => [ \App\Models\Profile::class => [ \App\Models\Indexes\IndexedUser::class, ], \App\Models\Company::class => [ \App\Models\Indexes\IndexedUser::class, \App\Models\Indexes\IndexedCompany::class, ], ], // Build state tracking (recommended to keep enabled) 'index_build_state' => [ 'enabled' => true, 'log_trim' => 2, // Keep last N log entries per record (null = no logs) ], // Migration logging (recommended to keep enabled) 'index_migration_logs' => [ 'enabled' => true, ], // Namespace mappings: Laravel model namespace => Index model namespace 'namespaces' => [ 'App\Models' => 'App\Models\Indexes', 'App\Domain\Users\Models' => 'App\Domain\Users\Indexes', ], // File paths for index model discovery 'index_paths' => [ 'app/Models/Indexes/' => 'App\Models\Indexes', 'app/Domain/Users/Indexes/' => 'App\Domain\Users\Indexes', ], ]; ``` -------------------------------- ### Configure Global Soft Delete Indexing Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Globally configure whether soft-deleted records should be indexed by setting `index_soft_deletes` to `true` in the `config/elasticlens.php` file. ```php // config/elasticlens.php 'index_soft_deletes' => true, ``` -------------------------------- ### Bulk Rebuild All Index Records for a Model Source: https://context7.com/pdphilip/elasticlens/llms.txt This command rebuilds all index records for a given model. It processes all records and displays a progress bar along with success and failure counts. ```php php artisan lens:build User ``` -------------------------------- ### Configure Watchers in elasticlens.php Source: https://context7.com/pdphilip/elasticlens/llms.txt Defines which indexes should be rebuilt when a specific model is updated. Add this configuration to your `config/elasticlens.php` file. ```php // config/elasticlens.php return [ 'watchers' => [ // When Profile is updated, rebuild these indexes \App\Models\Profile::class => [ \App\Models\Indexes\IndexedUser::class, ], // When Company is updated, rebuild these indexes \App\Models\Company::class => [ \App\Models\Indexes\IndexedUser::class, \App\Models\Indexes\IndexedCompany::class, ], ], ]; ``` -------------------------------- ### Convert Single Index Model to Base Model Source: https://context7.com/pdphilip/elasticlens/llms.txt Convert a single retrieved index model instance into its corresponding base Eloquent model instance using the `asBase()` method on the model. ```php asBase(); ``` -------------------------------- ### Paginate Results as Base Models (via viaIndex) Source: https://context7.com/pdphilip/elasticlens/llms.txt Paginate search results and receive them as base Eloquent models. This uses the standard `paginate()` method after enabling `viaIndex()`. ```php where('status', 'active') ->paginate(15); ``` -------------------------------- ### Configure Per-Model Soft Delete Indexing Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Configure soft delete indexing on a per-model basis by setting the `$indexSoftDeletes` property to `true` within your index model class. ```php // Or per index model class IndexedUser extends IndexModel { protected ?bool $indexSoftDeletes = true; } ``` -------------------------------- ### Track Index Build State with IndexableBuild Source: https://context7.com/pdphilip/elasticlens/llms.txt The IndexableBuild model tracks the state of index build operations, providing visibility into successes, failures, and skips. It is stored in Elasticsearch for fast querying. Use `IndexableBuild::isEnabled()` to check if tracking is active. ```php state->label(); // SUCCESS, FAILED, SKIPPED echo "Color: " . $state->state_color; // green, red, yellow echo "Last source: " . $state->last_source; echo "Data: " . json_encode($state->state_data); echo "Logs: " . json_encode($state->logs); } } ``` ```php // Count errors for an index model $errorCount = IndexableBuild::countModelErrors(IndexedUser::class); $skipCount = IndexableBuild::countModelSkips(IndexedUser::class); $totalCount = IndexableBuild::countModelRecords(IndexedUser::class); // Query failed builds $errors = IndexableBuild::buildErrorsQuery(IndexedUser::class) ->orderByDesc('created_at') ->limit(100) ->get(); foreach ($errors as $error) { echo "Model: {$error->model} #{$error->model_id}\n"; echo "Error: {$error->state_data['msg']}\n"; echo "Details: {$error->state_data['details']}\n"; } ``` ```php // Via IndexModel helper methods $allBuilds = IndexedUser::whereIndexBuilds(byLatest: true)->get(); $failedBuilds = IndexedUser::whereFailedIndexBuilds(byLatest: true)->get(); $migrations = IndexedUser::whereMigrations(byLatest: true)->get(); $migrationErrors = IndexedUser::whereMigrationErrors()->get(); // Delete state records IndexableBuild::deleteState('user', $userId, 'indexeduser'); IndexableBuild::deleteStateModel('indexeduser'); // Delete all for model ``` -------------------------------- ### Advanced Search with ElasticLens Query Builder Source: https://context7.com/pdphilip/elasticlens/llms.txt Access the full query builder using `viaIndex()` to apply more complex search criteria, filters, and pagination. This allows for fine-grained control over search queries. ```php // Access the full query builder via viaIndex() $users = User::viaIndex() ->searchPhrase('senior developer') ->where('status', 'active') ->orderByDesc('created_at') ->paginate(10); ``` -------------------------------- ### Build, Dry Run, Prepare, and Delete Index Records Source: https://context7.com/pdphilip/elasticlens/llms.txt Use RecordBuilder to manage Elasticsearch index records. It supports building/updating, dry-running for validation, preparing the index map, and deleting records. Ensure the index model class and model ID are provided. ```php success) { echo "Indexed successfully"; echo "Map: " . json_encode($result->map); } elseif ($result->skipped) { echo "Skipped: " . $result->msg; } else { echo "Failed: " . $result->msg; echo "Details: " . $result->details; } // Dry run - validate without saving $result = RecordBuilder::dryRun(IndexedUser::class, $userId); if ($result->success) { echo "Would index: " . json_encode($result->map); } // Prepare map only - get the data that would be indexed $result = RecordBuilder::prepareMap(IndexedUser::class, $userId); print_r($result->map); // Delete from index RecordBuilder::delete(IndexedUser::class, $userId); ``` ```php // Custom build with callback $result = RecordBuilder::customBuild( IndexedUser::class, $userId, 'Custom sync', function () use ($userId) { // Custom indexing logic $user = User::find($userId); $index = IndexedUser::find($userId) ?? new IndexedUser(); $index->id = $userId; $index->name = strtoupper($user->name); $index->save(); } ); ``` ```php // Build via trait methods $user = User::find(1); $result = $user->buildIndex(); // Via index model $indexed = IndexedUser::find(1); $result = $indexed->indexRebuild('Manual trigger'); // Static build method $result = IndexedUser::indexBuild($userId, 'API call'); ``` -------------------------------- ### Retrieve and Rebuild Model Index Records Source: https://context7.com/pdphilip/elasticlens/llms.txt Fetch a single model's corresponding Elasticsearch index record using `returnIndex()`. Manually trigger a rebuild of a model's index entry with `buildIndex()`, and remove it from the index using `removeIndex()`. ```php // Get a single model's index record $user = User::find(1); $indexRecord = $user->returnIndex(); // Manually trigger index rebuild for a model $result = $user->buildIndex(); // Remove a model from the index $user->removeIndex(); ``` -------------------------------- ### Set Custom Chunk Rate for Index Model Source: https://github.com/pdphilip/elasticlens/blob/main/CHANGELOG.md Define a custom chunk rate for migrations and builds by setting the `$buildChunkRate` property in your `IndexModel`. This controls the number of records processed per chunk. ```php class IndexedUser extends IndexModel { protected int $buildChunkRate = 2000; ``` -------------------------------- ### Query Elasticsearch Index Source: https://context7.com/pdphilip/elasticlens/llms.txt Perform direct queries against the Elasticsearch index using Eloquent-like syntax. Results are returned as index model instances. ```php $indexedUsers = IndexedUser::where('state', 'active')->get(); ``` -------------------------------- ### Fuzzy Search for Typos Source: https://context7.com/pdphilip/elasticlens/llms.txt Implement fuzzy searching to account for potential typos in search queries. Specify the fuzziness level to control the tolerance for character differences. ```php searchFuzzy('elastcsearch', fuzziness: 2) ->get(); ``` -------------------------------- ### Explicitly Paginate Results as Base Models Source: https://context7.com/pdphilip/elasticlens/llms.txt Paginate search results and explicitly retrieve them as base Eloquent models. The `paginateBase()` method ensures the results are converted to base models. ```php where('status', 'active') ->paginateBase(15); ``` -------------------------------- ### Basic Model Search Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Add the `Indexable` trait to your Eloquent model to enable basic search functionality. This allows for simple text searches across indexed fields. ```php User::search('mass donuts'); ``` -------------------------------- ### Phrase Search with Filters Source: https://context7.com/pdphilip/elasticlens/llms.txt Execute a phrase search for a specific string and apply filters to narrow down the results. This method is useful for exact matches within indexed documents. ```php searchPhrase('senior developer') ->where('status', 'active') ->where('company.industry', 'Technology') ->get(); ``` -------------------------------- ### Conditional Indexing in User Model Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Implement the `excludeIndex` method in your model to conditionally prevent records from being indexed. Excluded records are tracked as skipped. ```php class User extends Model { use Indexable; public function excludeIndex(): bool { return $this->is_banned; // bye } } ``` -------------------------------- ### Triggering Re-index via Model Save Source: https://context7.com/pdphilip/elasticlens/llms.txt Demonstrates how saving a model with the HasWatcher trait automatically triggers re-indexing of related models as configured. ```php // Now when a Profile is created/updated/deleted: $profile = Profile::find(1); $profile->bio = 'Updated bio'; $profile->save(); // This automatically triggers IndexedUser rebuild for the related user ``` -------------------------------- ### Define Field Mappings with Embedded Relationships Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Configure the `IndexedUser` model to map fields from the `User` model and embed related data from `Profile`, `Company`, and `UserLog` models. This flattens related data into a single searchable document. ```php class IndexedUser extends IndexModel { protected $baseModel = User::class; public function fieldMap(): IndexBuilder { return IndexBuilder::map(User::class, function (IndexField $field) { $field->text('first_name'); $field->text('last_name'); $field->text('email'); $field->type('state', UserState::class); // Embed the user's profiles as nested objects $field->embedsMany('profiles', Profile::class)->embedMap(function ($field) { $field->text('bio'); $field->array('tags'); }); // Embed the company they belong to $field->embedsBelongTo('company', Company::class)->embedMap(function ($field) { $field->text('name'); $field->text('industry'); }); // Last 10 logs only. We're not animals. $field->embedsMany('logs', UserLog::class, null, null, function ($query) { $query->orderBy('created_at', 'desc')->limit(10); })->embedMap(function ($field) { $field->text('action'); $field->text('ip'); }); }); } } ``` -------------------------------- ### Programmatically Check Index Health Source: https://context7.com/pdphilip/elasticlens/llms.txt Check the health of an index programmatically using the `lensHealth()` method on the index model. This returns an array with detailed status information. ```php 'Indexed Users', // 'indexModel' => 'IndexedUser', // 'state' => [ // 'index' => ['modelName' => 'IndexedUser', 'accessible' => true, 'records' => 1000], // 'model' => ['modelName' => 'User', 'accessible' => true, 'records' => 1000], // 'builds' => ['success' => 990, 'errors' => 5, 'skipped' => 5, 'total' => 1000], // 'status' => ['status' => 'warning', 'name' => 'Index Build Errors'] // ], // 'config' => [...] // ] ``` -------------------------------- ### Direct IndexModel Query Source: https://context7.com/pdphilip/elasticlens/llms.txt Execute a search query directly on an index model, bypassing the base Eloquent model. This is useful when you need to work with the raw index data or specific index model features. ```php searchTerm('developer') ->get(); ``` -------------------------------- ### Convert Index Results to Base Models Source: https://context7.com/pdphilip/elasticlens/llms.txt Convert the results obtained from an Elasticsearch query back into their corresponding base Laravel Eloquent models. ```php $users = IndexedUser::where('state', 'active')->get()->asBase(); ``` -------------------------------- ### Deep Health Check for a Specific Index Source: https://context7.com/pdphilip/elasticlens/llms.txt Use this command to check the health status of a specific index. It provides details on index accessibility, base model status, build errors, and configuration warnings. ```php php artisan lens:health User ``` -------------------------------- ### Geospatial Search and Sorting Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Find records within a specific geographic distance and sort them by proximity. This requires location data to be indexed correctly. ```php User::viaIndex() ->searchTerm('espressos') ->whereGeoDistance('home.location', '5km', [40.7128, -74.0060]) ->orderByGeo('home.location', [40.7128, -74.0060]) ->get(); ``` -------------------------------- ### Define IndexedUser Model and Field Mappings Source: https://context7.com/pdphilip/elasticlens/llms.txt Extend the `IndexModel` to define how a Laravel model maps to an Elasticsearch document. Configure field types, embedded relationships, and query constraints. ```php text('first_name'); $field->text('last_name'); $field->text('email'); $field->integer('age'); $field->bool('is_verified'); $field->carbon('created_at'); $field->array('tags'); // Enum fields $field->type('state', UserState::class); // Embed hasOne relationship $field->embedsOne('profile', Profile::class) ->embedMap(function ($embed) { $embed->text('bio'); $embed->text('website'); $embed->array('skills'); }); // Embed belongsTo relationship $field->embedsBelongTo('company', Company::class) ->embedMap(function ($embed) { $embed->text('name'); $embed->text('industry'); }); // Embed hasMany with query constraints $field->embedsMany('logs', UserLog::class, null, null, function ($query) { $query->orderBy('created_at', 'desc')->limit(10); })->embedMap(function ($embed) { $embed->text('action'); $embed->text('ip'); $embed->carbon('created_at'); }); // Disable observation for embedded model (won't trigger re-index) $field->embedsMany('archived_logs', UserLog::class) ->dontObserve() ->embedMap(function ($embed) { $embed->text('action'); }); }); } // Define Elasticsearch mapping (optional but recommended) public function migrationMap(): callable { return function (Blueprint $index) { $index->text('first_name'); $index->keyword('first_name'); $index->text('email'); $index->keyword('email'); $index->keyword('state'); $index->integer('age'); $index->boolean('is_verified'); $index->nested('profile'); $index->nested('company'); $index->nested('logs'); }; } } ``` -------------------------------- ### Advanced Search with Filters and Pagination Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Perform phrase searches with filters, embedded fields, and pagination. Use `viaIndex()` to access the full Elasticsearch query builder. ```php User::viaIndex() ->searchPhrase('mass donuts') ->where('status', 'active') ->where('logs.country', 'Norway') ->orderByDesc('created_at') ->paginate(10); ``` -------------------------------- ### Regex Search for Pattern Matching Source: https://context7.com/pdphilip/elasticlens/llms.txt Utilize regular expressions to search for patterns within specific fields. This is powerful for complex matching criteria, such as email formats. ```php whereRegex('email', '.*@company\.com') ->get(); ``` -------------------------------- ### Profile Model with HasWatcher Trait Source: https://context7.com/pdphilip/elasticlens/llms.txt Enables models not directly indexed to trigger re-indexing of related models. Ensure the model has a relationship to the indexed model. ```php belongsTo(User::class); } } ``` -------------------------------- ### Check Index Status Source: https://context7.com/pdphilip/elasticlens/llms.txt Displays the current status of all registered Elasticsearch indexes, including record counts and synchronization status. Useful for monitoring. ```bash # Check status of all registered indexes php artisan lens:status # Shows: Index names, record counts, sync status, errors ``` -------------------------------- ### Define Indexable Model with ElasticLens Source: https://context7.com/pdphilip/elasticlens/llms.txt Add the `Indexable` trait to your Eloquent model to enable Elasticsearch indexing. You can optionally define an `excludeIndex` method to conditionally prevent records from being indexed. ```php is_banned || $this->status === 'deleted'; } public function profile() { return $this->hasOne(Profile::class); } public function logs() { return $this->hasMany(UserLog::class); } } ``` -------------------------------- ### Add Indexable Trait to Model Source: https://github.com/pdphilip/elasticlens/blob/main/README.md To enable ElasticLens features, add the `Indexable` trait to your Eloquent model class. This is the first step in making your model searchable. ```php class User extends Model { use Indexable; } ``` -------------------------------- ### Search Across Embedded Relationships Source: https://github.com/pdphilip/elasticlens/blob/main/README.md Query data across embedded relationships defined in the `IndexedUser` model. This allows for complex searches involving data from multiple related tables without explicit SQL JOINs. ```php User::viaIndex() ->where('state', 'active') ->where('company.industry', 'Technology') ->where('profiles.bio', 'like', '%elasticsearch%') ->get(); ``` -------------------------------- ### Define User Index Field Mapping Source: https://context7.com/pdphilip/elasticlens/llms.txt Maps Laravel model attributes to Elasticsearch fields, supporting various types and relationship embeddings. Define this in your IndexModel. ```php text('name'); $field->text('bio'); // Integer fields $field->integer('age'); $field->integer('points'); // Boolean fields $field->bool('is_active'); $field->bool('is_verified'); // Array fields $field->array('tags'); $field->array('permissions'); // Carbon/DateTime fields $field->carbon('created_at'); $field->carbon('last_login_at'); // Enum or custom type fields $field->type('status', UserStatus::class); $field->type('metadata', 'array'); // embedsOne - One-to-one relationship (hasOne or belongsTo style) $field->embedsOne('profile', Profile::class) ->embedMap(function ($embed) { $embed->text('bio'); $embed->text('avatar_url'); $embed->array('social_links'); }); // embedsBelongTo - Parent relationship $field->embedsBelongTo('company', Company::class) ->embedMap(function ($embed) { $embed->text('name'); $embed->text('domain'); }); // embedsMany - One-to-many relationship $field->embedsMany('orders', Order::class) ->embedMap(function ($embed) { $embed->text('order_number'); $embed->integer('total'); $embed->carbon('ordered_at'); }); // embedsMany with custom foreign/local keys $field->embedsMany('reviews', Review::class, 'reviewer_id', 'id') ->embedMap(function ($embed) { $embed->text('content'); $embed->integer('rating'); }); // embedsMany with query constraints (limit, order, conditions) $field->embedsMany('recent_activities', Activity::class, null, null, function ($query) { $query->where('type', 'important') ->orderBy('created_at', 'desc') ->limit(5); })->embedMap(function ($embed) { $embed->text('description'); $embed->carbon('created_at'); }); // Disable observation on embedded model (changes won't trigger re-index) $field->embedsMany('archived_items', ArchivedItem::class) ->dontObserve() ->embedMap(function ($embed) { $embed->text('name'); }); }); } ``` ```php // If no fieldMap is defined, all model attributes are indexed as-is public function fieldMap(): IndexBuilder { return IndexBuilder::map(User::class); } ``` -------------------------------- ### Geo Distance Search Source: https://context7.com/pdphilip/elasticlens/llms.txt Perform searches based on geographical distance from a specified point. Requires location data to be indexed appropriately. Results can also be ordered by distance. ```php whereGeoDistance('location', '10km', [40.7128, -74.0060]) ->orderByGeo('location', [40.7128, -74.0060]) ->get(); ``` -------------------------------- ### Search Embedded Fields Source: https://context7.com/pdphilip/elasticlens/llms.txt Query data within nested or embedded fields in your Elasticsearch documents. This is useful for searching through arrays or objects within a document, like profiles or logs. ```php where('profiles.bio', 'like', '%elasticsearch%') ->where('logs.action', 'login') ->get(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.