Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)
Полнотекстовый поиск имеет решающее значение для того, чтобы пользователи могли ориентироваться на богатых контентом веб-сайтах. В этой статье я покажу вам, как реализовать полнотекстовый поиск в приложении Laravel. Фактически, мы будем использовать библиотеку Laravel Scout, которая делает реализацию полнотекстового поиска легкой и интересной.
Что такое Laravel Scout? Официальная документация описывает его следующим образом:
Laravel Scout предоставляет простое, основанное на драйверах решение для добавления полнотекстового поиска в ваши модели Eloquent. Используя наблюдателей модели, Scout автоматически синхронизирует поисковые индексы в с вашими записями Eloquent.
В основном, Laravel Scout - это библиотека, которая управляет манипулированием индексом всякий раз, когда происходит изменение данных модели. Место, где будут индексироваться данные, зависит от драйвера, который вы настроили с помощью библиотеки Scout.
На данный момент библиотека Scout поддерживает Algolia, облачный API для поисковых систем, и это то, что мы будем использовать в этой статье, чтобы продемонстрировать реализацию полнотекстового поиска.
Мы начнем с установки серверных библиотек Scout и Algolia, и по мере продвижения мы рассмотрим пример реального приложения, чтобы продемонстрировать, как вы можете индексировать и искать ваши данные.
Конфигурации сервера
В этом разделе мы собираемся установить зависимости, необходимые для того, чтобы библиотека Scout работала в Laravel. После установки нам нужно будет немного ее настроить, чтобы Laravel мог обнаружить библиотеку Scout.
Давайте продолжим и установим библиотеку Scout с помощью Composer.
$composer require laravel/scout
В значительной степени это касается установки библиотеки Scout. Теперь, когда мы установили библиотеку Scout, нужно удостовериться, что Laravel знает о ней.
Работая с Laravel, вы, вероятно, знаете концепцию поставщика услуг, которая позволяет вам настраивать службы в вашем приложении. Таким образом, всякий раз, когда вы хотите включить новую службу в своем приложении Laravel, вам просто нужно добавить соответствующую запись поставщика услуг в config/app.php
.
Если вы еще не знакомы с поставщиками услуг Laravel, я настоятельно рекомендую вам ознакомиться с этой вводной статьей, в которой объясняются основы поставщиков услуг в Laravel.
В нашем случае нам просто нужно добавить поставщика ScoutServiceProvider
в список поставщиков услуг в config/app.php
, как показано в следующем фрагменте.
... ... 'providers' => [ /* * Laravel Framework Service Providers... */ Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, Illuminate\Cookie\CookieServiceProvider::class, Illuminate\Database\DatabaseServiceProvider::class, Illuminate\Encryption\EncryptionServiceProvider::class, Illuminate\Filesystem\FilesystemServiceProvider::class, Illuminate\Foundation\Providers\FoundationServiceProvider::class, Illuminate\Hashing\HashServiceProvider::class, Illuminate\Mail\MailServiceProvider::class, Illuminate\Notifications\NotificationServiceProvider::class, Illuminate\Pagination\PaginationServiceProvider::class, Illuminate\Pipeline\PipelineServiceProvider::class, Illuminate\Queue\QueueServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class, Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, Illuminate\Session\SessionServiceProvider::class, Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, /* * Package Service Providers... */ Laravel\Tinker\TinkerServiceProvider::class, /* * Application Service Providers... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, Laravel\Scout\ScoutServiceProvider::class, ], ... ...
Теперь, Laravel знает о поставщике услуг ScoutServiceProvider
. Библиотека Scout поставляется с файлом конфигурации, который позволяет нам настраивать учетные данные API.
Двигаемся дальше и опубликуем ресурсы, предоставленные библиотекой Scout, используя следующую команду.
$ php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider" Copied File [/vendor/laravel/scout/config/scout.php] To [/config/scout.php] Publishing complete.
Как вы можете видеть, она скопировала файл vendor/laravel/scout/config/scout.php
в config/scout.php
.
Затем создайте учетную запись с Algolia, так как нам понадобятся учетные данные их API. После того, как у вас будет информация API, давайте продолжим и настроим необходимые параметры в файле config/scout.php
, как показано в следующем фрагменте.
<?php return [ /* |-------------------------------------------------------------------------- | Default Search Engine |-------------------------------------------------------------------------- | | This option controls the default search connection that gets used while | using Laravel Scout. This connection is used when syncing all models | to the search service. You should adjust this based on your needs. | | Supported: "algolia", "null" | */ 'driver' => env('SCOUT_DRIVER', 'algolia'), /* |-------------------------------------------------------------------------- | Index Prefix |-------------------------------------------------------------------------- | | Here you may specify a prefix that will be applied to all search index | names used by Scout. This prefix may be useful if you have multiple | "tenants" or applications sharing the same search infrastructure. | */ 'prefix' => env('SCOUT_PREFIX', ''), /* |-------------------------------------------------------------------------- | Queue Data Syncing |-------------------------------------------------------------------------- | | This option allows you to control if the operations that sync your data | with your search engines are queued. When this is set to "true" then | all automatic data syncing will get queued for better performance. | */ 'queue' => env('SCOUT_QUEUE', false), /* |-------------------------------------------------------------------------- | Chunk Sizes |-------------------------------------------------------------------------- | | These options allow you to control the maximum chunk size when you are | mass importing data into the search engine. This allows you to fine | tune each of these chunk sizes based on the power of the servers. | */ 'chunk' => [ 'searchable' => 500, 'unsearchable' => 500, ], /* |-------------------------------------------------------------------------- | Soft Deletes |-------------------------------------------------------------------------- | | This option allows you to control whether to keep soft deleted records in | the search indexes. Maintaining soft deleted records can be useful | if your application still needs to search for the records later. | */ 'soft_delete' => false, /* |-------------------------------------------------------------------------- | Algolia Configuration |-------------------------------------------------------------------------- | | Here you may configure your Algolia settings. Algolia is a cloud hosted | search engine which works great with Scout out of the box. Just plug | in your application ID and admin API key to get started searching. | */ 'algolia' => [ 'id' => env('ALGOLIA_APP_ID', 'STQK4DEGMA'), 'secret' => env('ALGOLIA_SECRET', '6ef572194f70201ed7ad102cc9f90e05'), ], ];
Обратите внимание, что мы установили значение SCOUT_DRIVER
для драйвера algolia
. Таким образом, вам необходимо настроить необходимые параметры для драйвера Algolia в конце файла. В принципе, вам просто нужно установить id
и secret
, которые вы получили из учетной записи Algolia.
Как вы можете видеть, мы извлекаем значения из переменных среды. Поэтому давайте проверим, правильно ли заданы следующие переменные в файле .env
.
... ... ALGOLIA_APP_ID=STQK4DEGMA ALGOLIA_SECRET=6ef572194f70201ed7ad102cc9f90e05 ... ...
Наконец, нам нужно установить SDK Algolia PHP, который будет использоваться для взаимодействия с API-интерфейсами Algolia. Давайте установим его с помощью Composer, как показано в следующем фрагменте.
$composer require algolia/algoliasearch-client-php
И при этом мы установили все зависимости, необходимые для публикации и индексации данных в службу Algolia.
Делаем модели индексируемыми и доступными для поиска
В предыдущем разделе мы проделали большую работу по настройке библиотек Scout и Algolia, чтобы мы могли индексировать и искать данные с помощью службы поиска Algolia.
В этом разделе мы рассмотрим пример, демонстрирующий, как вы можете индексировать существующие данные и извлекать результаты поиска из Algolia. Я предполагаю, что у вас есть модель по умолчанию Post
, которую мы будем использовать в нашем примере.
Первое, что нам нужно сделать, это добавить трейт Laravel\Scout\Searchable
к модели Post
. Это делает модель Post
доступной для поиска; Laravel синхронизирует записи с индексом Algolia каждый раз, когда Post-запись добавляется, обновляется или удаляется.
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; class Post extends Model { use Searchable; /** * The attributes that should be mutated to dates. * * @var array */ protected $dates = [ 'created_at', 'updated_at' ]; }
При этом модель Post
удобна для поиска!
Затем мы хотим настроить поля, которые должны быть проиндексированы в первую очередь. Конечно, вы не хотите индексировать все поля вашей модели в Algolia, чтобы они были эффективными и легкими. На самом деле, чаще всего это вам не понадобится.
Вы можете добавить toSearchableArray
в класс модели для настройки полей, которые будут проиндексированы.
/** * Get the indexable data array for the model. * * @return array */ public function toSearchableArray() { $array = $this->toArray(); return array('id' => $array['id'],'name' => $array['name']); }
Теперь мы готовы импортировать и индексировать существующие записи Post
в Algolia. Фактически, библиотека Scout облегчает это, предоставляя следующую команду artisan.
$php artisan scout:import "App\Post"
Это должно импортировать все записи модели Post
за один раз! Они индексируются, как только они импортируются, поэтому мы уже готовы запросить записи. Двигаемся дальше и исследуем дашборд Algolia, чтобы увидеть импортированные записи и другие утилиты.
Как это работает
В этом разделе мы создадим пример, демонстрирующий, как выполнять операции поиска и CRUD, которые синхронизируются в реальном времени с индексом Algolia.
Идем дальше и создаем файл app/Http/Controllers/SearchController.php
со следующим содержимым.
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use App\Post; class SearchController extends Controller { public function query() { // queries to Algolia search index and returns matched records as Eloquent Models $posts = Post::search('title')->get(); // do the usual stuff here foreach ($posts as $post) { // ... } } public function add() { // this post should be indexed at Algolia right away! $post = new Post; $post->setAttribute('name', 'Another Post'); $post->setAttribute('user_id', '1'); $post->save(); } public function delete() { // this post should be removed from the index at Algolia right away! $post = Post::find(1); $post->delete(); } }
Конечно, нам нужно также добавить соответствующие маршруты.
Route::get('search/query', 'SearchController@query'); Route::get('search/add', 'SearchController@add'); Route::get('search/delete', 'SearchController@delete');
Давайте рассмотрим метод query
, чтобы узнать, как выполнить поиск в Algolia.
public function query() { // queries to Algolia search index and returns matched records as Eloquent Models $posts = Post::search('title')->get(); // do the usual stuff here foreach ($posts as $post) { // ... } }
Напомним, что мы сделали модель Post
доступной для поиска, добавив трейт Searchable
. Таким образом, модель Post
может использовать метод search
для извлечения записей из индекса Algolia. В приведенном выше примере мы пытаемся получить записи, соответствующие ключевому слову title
.
Затем есть метод add
, который имитирует рабочий процесс добавления новой записи записи.
public function add() { // this post should be indexed at Algolia right away! $post = new Post; $post->setAttribute('name', 'Another Post'); $post->setAttribute('user_id', '1'); $post->save(); }
В приведенном выше коде нет ничего необычного; он просто создает новую запись после использования модели Post
. Но модель Post
реализует трейт Searchable
, поэтому Laravel делает некоторую дополнительную работу на этот раз, индексируя вновь созданную запись в Algolia. Итак, как вы можете видеть, индексирование выполняется в режиме реального времени.
Наконец, существует метод delete
. Давайте также рассмотрим и его.
public function delete() { // this post should be removed from the index at Algolia right away! $post = Post::find(1); $post->delete(); }
Как и следовало ожидать, запись удаляется сразу же из индекса Algolia, как только она удаляется из базы данных.
В принципе, с вашей стороны не требуется дополнительных усилий, если вы хотите, чтобы существующие модели были доступны для поиска. Все обрабатывается библиотекой Scout с использованием наблюдателей модели.
На этом мы заканчиваем нашу статью!
Заключение
Сегодня мы обсудили, как можно реализовать полнотекстовый поиск в Laravel с помощью библиотеки Laravel Scout. В этом процессе мы прошли необходимые установки и продемонстрировали реальный пример.
Не стесняйтесь спрашивать, есть ли у вас какие-либо вопросы или сомнения, используя приведенный ниже канал для комментариев.
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post