The search function is a function that any large or small project needs. And no exception, in a laravel project I’m doing using elasticsearch so today I would like to introduce to you about the package scout-elasticsearch-driver.
1. What is Laravel Scout?
Laravel Scout is full-text search based on driver for Eloquent. In addition, it supports Algolia, Elastic Search, and because it is full-text search based on driver, anyone can create their own integration with other full-text search systems.
Laravel Scout works based on it adding search properties to existing models. Then just synchronize the data with the search service.
2. What is Elasticsearch?
- Elasticsearch is a distributed, RESTful open source search and analysis tool built on Apache Lucene. Since its release, Elasticsearch has quickly become the most popular and widely used search engine.
- Elasticsearch actually works like a web server, able to search quickly through RESTful protocol.
3. How to install the package
- To install, we just need to use the composer:
12composer require babenkoivan/scout-elasticsearch-driver - If you use laravel version <= 5.4, you will add providers to config / app.php:
12345'providers' => [LaravelScoutScoutServiceProvider::class,ScoutElasticScoutElasticServiceProvider::class,] - After successfully installing the package, use the following command line to publish config:
123php artisan vendor:publish --provider="LaravelScoutScoutServiceProvider"php artisan vendor:publish --provider="ScoutElasticScoutElasticServiceProvider" - This command will automatically create the settings in config / scout.php and config / scout_elastic.php. And we can change some of its original configuration. You can refer to here So we have successfully installed the package already.
4. How to use the package in project laravel
1. Create IndexConfigurator
- Each Eloquent Model will synchronize with an index search index, containing all searchable records for that model. In other words, you can simply understand the index in Elasticsearch as a table, but it’s not exactly the same.
- An index configurator is used to set an index search index. To create an index configurator we use the following command: Note that the name of each index configurator will have to be different.
12php artisan make:index-configurator MyIndexConfigurator - This will create a MyIndexConfigurator.php file in the app directory. Here you can name and settings for the index configurator (You can refer to other settings here )
Example: I have a simple VD setting below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php namespace App; use ScoutElasticIndexConfigurator; class MyIndexConfigurator extends IndexConfigurator { // It's not obligatory to determine name. By default it'll be a snaked class name without `IndexConfigurator` part. protected $name = 'my_index'; /** * You can specify any settings you want, for example, analyzers. * @var array */ protected $settings = [ 'analysis' => [ 'analyzer' => [ 'custom_analyzer' => [ 'type' => 'custom', 'tokenizer' => 'keyword', 'filter' => [ 'lowercase' ], ], ], ], ]; } |
And for index configurator to work we need to run the following command:
1 2 |
php artisan elastic:create-index "AppMyIndexConfigurator" |
Similarly, when you edit the settings and you want to update the index configurator, you can run the command:
1 2 |
php artisan elastic:update-index "AppMyIndexConfigurator" |
Delete an index configurator:
1 2 |
php artisan elastic:drop-index "AppMyIndexConfigurator" |
2. Create Searchable Model
In fact, this step is mostly done in practice, we have already created corresponding models for each search index. But I still show you how to create a Searchable Model nhes
- To create a Searchable Model we use the following command:
12php artisan make:searchable-model Models/MyModel --index-configurator=MyIndexConfigurator - This will create an app / Models / MyModel.php file that looks like this:
1234567891011121314151617181920212223242526272829303132333435363738394041424344<?phpnamespace AppModels;use ScoutElasticSearchable;use AppMyIndexConfigurator;use IlluminateDatabaseEloquentModel;class MyModel extends Model{use Searchable;protected $indexConfigurator = MyIndexConfigurator::class;// Here you can specify a mapping for model fieldsprotected $mapping = ['properties' => ['title' => ['type' => 'text',// Also you can configure multi-fields, more details you can find here https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html'fields' => ['raw' => ['type' => 'keyword',]]],]];/*** Get the indexable data array for the model.** @return array*/public function toSearchableArray(){$array = $this->toArray();// Customize array...return $array;}} - Inside:
- Mapping is the process of defining how a document and its fields are stored and indexed. Specifically, use mapping to define: type, format, .. for each model fields.
- The function toSearchableArray () is used to customize the data to synchronize with each search index. I see a pretty good post about customizing searchable data, please refer here !
- If we already have a model already, just use Searchable, declare the configurator, $ mapping and the function toSearchableArray ().
- And to synchronize the data, we need to run the command:
12php artisan elastic:update-mapping "AppModelsMyModel"
3. Use
- Because this is a combination package of scout and elasticsearch, after completing the above steps, we need to add an extremely important step that is to import data into each index through the following command:
php artisan scout:import "AppModelsMyModel"
- Also when CRUD a record is automatically added to the search index, after doing so we add:
123456// Create + Update$record->searchable();// Delete$record->unsearchable(); - Now through the Model you can start searching using the search () method, you can see more here !
12MyModel::search($inputs)->get();
4. Search rules
1 2 3 4 5 6 |
Tuy nhiên khi thực hiện các query search chắc chắn không thể loại trừ ngoại lệ bạn muốn custom request, để tránh bị rối thì bạn nên tạo một class Search rules: ``` php artisan make:search-rule MySearchRule ``` Câu lệnh tạo ra một file app/MySearchRule.php có dạng như sau: |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?php namespace App; use ScoutElasticSearchRule; class MySearch extends SearchRule { // This method returns an array, describes how to highlight the results. // If null is returned, no highlighting will be used. public function buildHighlightPayload() { return [ 'fields' => [ 'name' => [ 'type' => 'plain' ] ] ]; } // This method returns an array, that represents bool query. public function buildQueryPayload() { return [ 'must' => [ 'match' => [ 'name' => $this->builder->query ] ] ]; } } |
In the model you add $ searchRules property:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php namespace AppModels; use ScoutElasticSearchable; use IlluminateDatabaseEloquentModel; class MyModel extends Model { use Searchable; // You can set several rules for one model. In this case, the first not empty result will be returned. protected $searchRules = [ MySearchRule::class ]; } |
5. Debug
- The package also provides two methods that can help us analyze search query results:
1 2 3 |
AppModelsMyModel::search('Brazil') ->explain(); |
1 2 3 |
AppModelsMyModel::search('Brazil') ->profile(); |