elastic-scout-driver-plus icon indicating copy to clipboard operation
elastic-scout-driver-plus copied to clipboard

Make ElasticScoutDriverPlus\Engine non final, so that can be extended in order to prioritize models' indexing based on custom rules

Open marcelopm opened this issue 2 years ago • 2 comments

We are migrating from the old driver, where we managed to prioritize the indexing of models' data according to their size by creating a custom Indexer and use it instead of the Simple or Bulk indexers that comes out of the box with that driver.

We need to refactor our solution into something that can be used with the new ecosystem, which this driver is part of.

Reasons why we want to be able to overwrite ElasticScoutDriverPlus\Engine::update()

  • We can't calculate and don't want to read the model's data size at dispatch time of MakeSearchable job for performance reasons. (We calculate it and store it previously, so it can be used later to decide if the models being indexed are too big and should be indexed by a new job that gets treated with a lower priority, making models with little data to be indexed first)
  • Looking at the new architecture, looks like there isn't any other better places to do this other than in the method below, since toSearchableArray() get's called before $this->documentManager->index().
    public function update($models)
    {
        if ($models->isEmpty()) {
            return;
        }

        $indexName = $models->first()->searchableAs();
        $routing = $this->routingFactory->makeFromModels($models);
        $documents = $this->documentFactory->makeFromModels($models); //<-- toSearchableArray is called in here, so the decision of which of the models should be indexed now and which should be deferred needs to happen before 

        $this->documentManager->index($indexName, $documents, $this->refreshDocuments, $routing);
    }

UPDATE: we know we can work around this by using a Decorator, but we'd like to avoid it if possible.

marcelopm avatar Jul 20 '22 23:07 marcelopm

Hey @marcelopm, what ES version do you use? I can surely do it, but only in the new version 4.0, which only supports ES8. I'm not planning to support the previous version due to a lack of time.

Side note: have you considered creating a custom MakeSearchable job and then replacing the default one in the service provider?

function boot() 
{
     Scout::$makeSearchableJob = MyMakeSearchable::class;
}

babenkoivan avatar Jul 29 '22 07:07 babenkoivan

That's great, thanks for considering it @babenkoivan

We do that already. As part of the solution we came up with, we created a custom MakeSearchable job and overridden the handle() method so that we can pass the current job instance to the update method, as below:

        $this
            ->models
            ->first()
            ->searchableUsing()
            ->update($this->models, $this);

We created also other job classes that extends it.

This allow us to dispatch specific MakeSearchable alike jobs and, more importantly, decide how we want to handle them during (re)indexing of models' data, as mentioned initially.

marcelopm avatar Aug 01 '22 02:08 marcelopm

Hi @marcelopm, just FYI: Engine is now non-final since v4.0.2.

babenkoivan avatar Aug 15 '22 06:08 babenkoivan