Search code examples
phplaravelfull-text-searchlaravel-artisanlaravel-scout

laravel scout: How to update index in controller


Here is my question. I want to update the scout index saved in storage in my controller. Any ideas how to do it?

I am using tntsearch package. I know I can do artisan command in command prompt with $ php artisan scout:import App\\Models\\Paper

But I'm working on a website that everyone can submit their journals in it and I need a powerful search engine on my website. So in this situation, I need to update the index every time a journal submitted. So that everyone can be able to search the journals.

I manage to do a part of this task by making a provider TNTSearchScoutServiceProvider.

here is TNTSearchScoutServiceProvider:

class TNTSearchScoutServiceProvider extends \TeamTNT\Scout\TNTSearchScoutServiceProvider
{
    public function boot()
    {
        $this->app[EngineManager::class]->extend('tntsearch', function ($app) {
            $tnt = new TNTSearch();

            $driver = config('database.default');
            $config = config('scout.tntsearch') + config("database.connections.{$driver}");

            $tnt->loadConfig($config);
            $tnt->setDatabaseHandle(app('db')->connection()->getPdo());

            $this->setFuzziness($tnt);
            $this->setAsYouType($tnt);

            return new TNTSearchEngine($tnt);
        });


        // To allow us run commands if we're not running in the console
        $this->commands([
            ImportCommand::class,
        ]);
    }
}

After adding this provider to config/app.php. In the controller I am using the provider like this:

Artisan::call('tntsearch:import', ['model' => 'App\Models\Paper']);

But this throwes this error:

unlink(C:\wamp64\www\mywbsite\storage/papers.index): Resource temporarily unavailable

Here is what I accomplish so far: although it throws the error,but I can only get the last updated row in search results and the oldest rows doesn't show up in the search results.

So what are your suggestions? Is it a better way to do this? Or I should check out the site every day and run the artisan commands so that the table can be indexed?


Solution

  • I finally managed to solve this problem:

    to update the index in storage you just make a new obj from TNTindexer class; First, you create that index and after that, you select the columns you want to update with query() method. then run() the indexer.Before that make sure to load the configuration. here is the method that I write in the controller:

       protected function add_to_search(){
    
            $indexer = new TNTIndexer;
    
            $driver = config('database.default');
            $config = config('scout.tntsearch') + config("database.connections.{$driver}");
    
            $indexer->loadConfig($config);
    
            $indexer->createIndex('paper.index');
            $indexer->query('SELECT id,title,description,abstract,keywords FROM papers;');
            $indexer->run();
        }
    

    this way the index always updated through a controller.