Skip to content

What's New in V4

Three things: a cleaner search API, conditional indexing, and soft delete support.

The big one. viaIndex() now returns Base Models by default.

In v3, viaIndex()->get() returned Index Models and you had to call getBase() to get your actual models back. That’s backwards. In v4, get() and paginate() return base models when called through viaIndex():

// v3 - extra step
User::viaIndex()->searchTerm('david')->getBase();
// v4 - just works
User::viaIndex()->searchTerm('david')->get();

When you do want index models, ask for them explicitly:

  • getIndex() / paginateIndex() / firstIndex() - Returns Index Models
  • getBase() / paginateBase() / firstBase() - Still available, now just aliases for the default

New excludeIndex() method on your Base Model. Skip records that don’t belong in the index:

class User extends Model
{
use Indexable;
public function excludeIndex(): bool
{
return $this->status === 'banned';
}
}

Excluded records show up as skipped in build state and health checks. See Conditional Indexing for details.

ElasticLens now handles soft deletes properly:

  • Global config: index_soft_deletes in config/elasticlens.php
  • Per-model override: $indexSoftDeletes property on your Index Model
  • Restore detection: Automatically re-indexes when a model is restored
config/elasticlens.php
'index_soft_deletes' => true, // Keep index records when soft deleting
// Or per-model
class IndexedUser extends IndexModel
{
protected ?bool $indexSoftDeletes = true;
}

See Soft Delete Support for the full configuration guide.

New lens:errors command to inspect build failures for a specific model:

Terminal window
php artisan lens:errors User

Shows each failed record with error message, details, source, and timestamp. Paginated with a prompt to view more.

lens:migrate now uses the same bulk insert engine as lens:build. Previously it rebuilt records one at a time. Same result, significantly faster on large datasets.

Under the hood, ElasticLens now uses a dedicated LensBuilder that extends the Elasticsearch Builder. This powers the viaIndex scope flag and gives the search API a cleaner architecture. IndexModel::query() returns a LensBuilder instance.