Hi everyone,
This is probably a duplicate of @bobmulder's post from a few years back, but since it didn’t receive a clear answer and I’ve been stuck on this for a while, I’m asking for help again.
Using PostgreSQL’s jsonb capabilities, I’ve built a structure similar to EAV, with sources and records.
I want to index and search records using a dynamic index name based on the $source->index field.
Dynamic searchableAs() approach
This works fine when indexing records as they’re created:
public function searchableAs(): string
{
return Str::of('source_')->append($this->source->index)->lower();
}
However, running something like php artisan scout:refresh or php artisan scout:import throws the following error:
$ php artisan scout:refresh "App\Models\Records"
Attempt to read property "index" on null
Fallback "dumb" index
To avoid the error, I added a fallback value:
public function searchableAs(): string
{
if (! $this || ! $this->source) {
return 'empty_source';
}
return Str::of('source_')->append($this->source->index)->lower();
}
This works, but it creates an unwanted and useless empty_source index. Worse, I realized that searchableAs() is only called once during indexing, meaning all records get grouped under the first source's index—completely mixing different datasets.
Is searchableAs() the right approach?
An alternative would be to index all records under a shared index and include the source identifier in toSearchableArray(), then filter results via custom queries. But that feels wrong, as the records are semantically very different and likely belong in separate schemas.
What would be the cleanest and most maintainable way to handle this?