laravel / scout

Laravel Scout provides a driver based solution to searching your Eloquent models.
https://laravel.com/docs/scout
MIT License
1.54k stars 327 forks source link

Optimization of Reindexing in Laravel Scout #816

Closed jjdevzinho closed 5 months ago

jjdevzinho commented 5 months ago

I'm using Laravel Scout in a project and I've noticed that Scout reindexes a model whenever it's updated, regardless of which fields were changed. This can be inefficient in situations where I have fields that are frequently updated but don't affect search results, such as view or like counters.

It would be helpful if Scout provided a way to control when models are reindexed based on which fields were changed. For example, there could be an additional method that we can override in the model, like getSearchableFields, which returns a list of fields that should trigger reindexing when changed. Scout could then check if any of these fields were changed before reindexing the model.

Here's an example of how this could work:

public function getSearchableFields()
{
    return ['name', 'description', 'price'];
}

With this modification, Scout would only reindex the model if name, description, or price were changed. This could help to reduce the amount of unnecessary reindexing and improve the efficiency of Scout.

Thank you for considering my suggestion.

jjdevzinho commented 5 months ago

Another idea could be to leverage the toSearchableArray method that already exists in Scout. This method returns an array of the model's attributes that should be indexed.

Instead of creating a new getSearchableFields method, Scout could check if any of the keys returned by toSearchableArray were changed before reindexing the model. This would avoid the need to define the searchable fields in two places and make the reindexing process more efficient.

Here's an example of how this could work:

// Get the keys from the toSearchableArray method
$searchableFields = array_keys($model->toSearchableArray());

// Check if any of these fields were changed
foreach ($searchableFields as $field) {
    if ($model->isDirty($field)) {
        // If a searchable field was changed, reindex the model
        $model->searchable();
        break;
    }
}

This approach would require changes to the Scout core, but it could be a more efficient way to control when reindexing occurs.

Thank you for considering my suggestion and this additional idea.

driesvints commented 5 months ago

We'd very much appreciate PR's which could help with optimisation. For these PR's please also include the proper benchmarks. Thanks