Full text search solution: Larravel Scout
brief introduction
Larravel Scout is Eloquent model Full text search implementation provides a simple, driver based solution. By using a model observer, Scout automatically updates the index of model records synchronously.
At present, Scout has passed the Algolia The driver provides the search function. However, it is easy to write a custom driver. You can easily extend Scout through your own search implementation.
Note: Algolia is a managed full-text search engine. We can quickly realize real-time search function in websites and mobile applications through its API. Algolia provides services for a fee, but we can use its free version for testing. The free version supports 10000 records/100000 operations.
install
First, we use Composer package manager to install Scout:
composer require laravel/scout
After installation, you need to use the Artisan command vendor:publish
Publish Scout configuration. This command will publish the configuration file scout.php
reach config
catalog:
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
Finally, if you want a model to support Scout search, you need to add Laravel\Scout\Searchable
Trait to the corresponding model class, which will register the model observer to maintain the consistency between the search driver and the model record data:
<? php namespace App; use Laravel\Scout\Searchable; use Illuminate\Database\Eloquent\Model; class Post extends Model { use Searchable; }
queue
Although not mandatory, it is strongly recommended to configure a Queue driven 。 Running a queue process will allow Scout to push all synchronization model information to the search index to the queue, thus providing faster response time for the application's Web interface.
After configuring the queue driver config/scout.php
Set in queue
The value of the option is true
:
'queue' => env('SCOUT_QUEUE', true),
Drive preparatory knowledge
Algolia
To use the Algolia driver, you need to check the configuration file config/scout.php
Set Algolia's id
and secret
Information (This information can be found in the user's background after logging in to Algolia, corresponding to the Application ID and Admin API Key under API Keys respectively). After configuration, you need to install the Algolia PHP SDK through the Composer package manager:
composer require algolia/algoliasearch-client-php
to configure
Configure Model Index
Each Eloquent model is synchronized through a given search "index", which contains all searchable model records. In other words, you can think of the index as a MySQL data table. By default, each model will be persisted to the index matching the table name of the model (usually the plural form of the model name). However, you can override the searchableAs
Method to override this default setting:
<? php namespace App; use Laravel\Scout\Searchable; use Illuminate\Database\Eloquent\Model; class Post extends Model { use Searchable; /** *Get the index name of the model * * @return string */ public function searchableAs() { return 'posts_index'; } }
Configure Search Data
By default, the model uses the full toArray
The format is persisted to the search index. If you want to customize the data persisted to the search index, you can overwrite the toSearchableArray
method:
<? php namespace App; use Laravel\Scout\Searchable; use Illuminate\Database\Eloquent\Model; class Post extends Model { use Searchable; /** *Get the index data array of the model * * @return array */ public function toSearchableArray() { $array = $this->toArray(); //Custom Array return $array; } }
Indexes
Batch import
If you install Scout into an existing project, there may have been database records that can be imported into search driven databases before the project. Scout provides Artisan commands import
Used to import all existing data to the search index:
php artisan scout:import "App\Post"
After the import is successful, we can see the index data successfully imported in the background of Algolia:
Add Record
add to Laravel\Scout\Searchable
After the trait is added to the model, all you need to do is save the model instance, and then the instance will be automatically added to the model index. If you have configured Scout Use Queue , the operation will be pushed to the queue for execution in the background:
$post = new App\Post; $post ->title='What is Scout '; $post ->content='Scout is an official full-text search solution provided by Larvel '; $post->user_id = 1; $post->save();
After the model data is saved, it will also be synchronized to Algolia through Scout:
Add by Query
If you want to add the model collection to the search index through Eloquent query, you can append it after Eloquent query searchable
Method call. searchable
Method score Chunking Query and add the results to the search index. Again, if you configure Scout to use queues, all chunk queries will be pushed to the queue in the background:
//Add by Eloquent Query App\Post::where('user_id', '>', 10)->searchable(); //You can also add records through association $user->posts()->searchable(); //You can also add records through collections $posts->searchable();
searchable
The method will perform the "upsert" operation. In other words, if the model record already exists in the index, it will be updated. If it does not exist, it will be added.
Update records
To update the model that supports search, simply update the properties of the model instance and save the model to the database. Scout will automatically persist updates to the search index:
$post = App\Post::find(2); $post ->title='Who is the academic gentleman '; $post ->content='Academician created Laravel College, hence the name'; $post->save();
Go to Algolia to check the index data, which has been updated:
You can also use the searchable
Method to update the model collection. If the model does not exist in the search index, it will be created:
//Update by Eloquent Query App\Post::where('user_id', '>', 10)->searchable(); //You can also update by association $user->posts()->searchable(); //You can also update through collections $posts->searchable();
Delete Record
To delete a record from the index, just delete the corresponding record from the database. This deletion method is even compatible Soft Delete Model:
$post = App\Post::find(1); $post->delete();
If you don't want to get the model before deleting records, you can use the model to query the unsearchable
method:
//Remove by Eloquent Query App\Post::where('user_id', '>', 10)->unsearchable(); //You can also remove it through association $user->posts()->unsearchable(); //You can also remove $posts->unsearchable();
Pause Indexing
Sometimes you need to perform batch Eloquent operations without synchronizing model data to the search index withoutSyncingToSearch
Method. This method receives a callback that is executed immediately. All model operations in this callback will not be synchronized to the search index:
App\Post::withoutSyncingToSearch(function () { // Perform model actions... });
search
You can search
Method to search a model. This method receives a string used to search the model. Then you need to call a get
Method to obtain the Eloquent model matching the given search query:
$posts=App Post:: search ('college ') ->get();
Since Scout search returns Eloquent model sets, you can even return results directly from routes or controllers, which will be automatically converted to JSON format:
use Illuminate\Http\Request; Route::get('/search', function (Request $request) { return App\Post::search($request->search)->get(); });
When searching for "Academy", two search results are returned:
If you want to get the original search results instead of the converted Eloquent model, you can use raw
method:
$posts=App Post:: search ('college ') ->raw();
The returned data is as follows:
The search query uses the searchAs
Method. However, you can also use the within method to specify a custom index for searching:
$posts=App Post:: search ('college ') ->within('users_index') ->get();
Where clause
Scout allows you to add simple where clauses to search queries. Currently, these clauses only support simple numeric equality checks. Since search indexes are not relational databases, more advanced where clauses do not support:
$posts=App Post:: search ('Academy ') ->where ('user_id', 1) ->get();
paging
In addition to obtaining the model collection, you can also use the paginate
Method to paginate the search results. This method returns a Paginator
Example - just like you Paging traditional Eloquent queries Same:
$posts=App Post:: search ('college ') ->paginate();
The returned results are as follows:
You can pass in the quantity as paginate
The first parameter of the method specifies how many models are displayed per page:
$posts=App Post:: search ('college ') ->paginate (15);
After obtaining the results, you can use the Blade Display the results and render paging links, just like paging traditional Eloquent queries:
@foreach ($orders as $order) {{ $order->price }} @endforeach
{{ $orders->links() }}
Custom Engine
Writing engine
If a built-in Scout search engine does not meet your needs, you can write a customized engine and register it with Scout. The customized engine needs to inherit from an abstract class Laravel\Scout\Engines\Engine
, this abstract class contains seven methods that the custom engine must implement:
use Laravel\Scout\Builder; abstract public function update($models); abstract public function delete($models); abstract public function search(Builder $builder); abstract public function paginate(Builder $builder, $perPage, $page); abstract public function mapIds($results); abstract public function map($results, $model); abstract public function getTotalCount($results);
The implementation of these methods can be referred to Laravel\Scout\Engines\AlgoliaEngine
Class, which provides the best template for us to learn how to implement these methods in the custom engine.
Registration Engine
After writing a custom engine, you can use the extend
Method to register it to Scout. You need to AppServiceProvider
(or other service providers) boot
This is called in the extend
method. For example, if you write MySqlSearchEngine
, you can register as follows:
use Laravel\Scout\EngineManager; /** *Start any application service * * @return void */ public function boot() { resolve(EngineManager::class)->extend('mysql', function () { return new MySqlSearchEngine; }); }
After the engine is registered, the configuration file config/scout.php
Set it as the default driver of Scout:
'driver' => env('SCOUT_DRIVER', 'mysql'),