Інтеграція Typesense з Laravel

Typesense — це швидкий, відкритий пошуковий движок, оптимізований для миттєвих, релевантних та стійких до помилок пошукових результатів. Він відмінно підходить для додатків, які потребують розширених можливостей пошуку, і є простим у використанні.

Laravel Scout — це пакет для Laravel, який надає простий інтерфейс для інтеграції повнотекстового пошуку у ваші моделі Eloquent. Я надає просте рішення на основі драйвера для додавання повнотекстового пошуку до ваших моделей.
Використовуючи спостерігачів моделей (model observers), Scout автоматично синхронізує ваші індекси пошуку з записами в Eloquent.

У цій статті я поясню, як налаштувати Typesense з Laravel, а також його схему проектування і використання в get API.

Інтеграція

Спочатку потрібно встановити пакети через composer:

composer require typesense/typesense-php  
composer require laravel/scout  
composer require typesense/laravel-scout-typesense-engine

Після цього слід опублікувати конфігураційний файл Scout, використовуючи наступну команду.
Ця команда опублікує конфігураційний файл scout.php у директорії конфігурацій вашого додатку:

php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

Додайте наступні рядки у файл .env

SCOUT_DRIVER=typesense  
TYPESENSE_API_KEY=your_api_key  
TYPESENSE_HOST=127.0.0.1  
TYPESENSE_PORT=8108  
TYPESENSE_PROTOCOL=http

Щоб зробити модель пошуковою

 [  
 'client-settings' => [  
 'api_key' => env('TYPESENSE_API_KEY', 'abc'),  
 'nodes' => [  
 [  
 'host' => env('TYPESENSE_HOST', 'localhost'),  
 'port' => env('TYPESENSE_PORT', '0000'),  
 'path' => env('TYPESENSE_PATH', ''),
'protocol' => env('TYPESENSE_PROTOCOL', 'http'),  
 ],  
 ],  
 'nearest_node' => [  
 'host' => env('TYPESENSE_HOST', 'localhost'),  
 'port' => env('TYPESENSE_PORT', '0000'),  
 'path' => env('TYPESENSE_PATH', ''),  
 'protocol' => env('TYPESENSE_PROTOCOL', 'http'),  
 ],  

 ],  

 'model-settings' => [  
 \App\Models\v1\User::class => [  
 'collection-schema' => [  
 'fields' => [  
 ['name' => 'id', 'type' => 'string', 'index' => true],  
 ['name' => 'email', 'type' => 'string', 'index' => true, 'optional' => true],  
 ['name' => 'phone', 'type' => 'string', 'index' => true, 'optional' => true],  
 ]  
 ]  
 ]  
 ],  
 ],

Наприклад, модель User має відношення один до одного з моделлю Country. У такому випадку потрібно оновити вашу схему.

'collection-schema' => [  
 'fields' => [  
 ['name' => 'id', 'type' => 'string', 'index' => true],  
 ['name' => 'email', 'type' => 'string', 'index' => true, 'optional' => true],
['name' => 'phone', 'type' => 'string', 'index' => true, 'optional' => true],  
 ['name' => 'country_id', 'type' => 'string', 'index' => true, 'reference' => 'countries.id'],  
 ]  
 ]

Тепер припустимо, що модель User має кілька записів про автомобілі (один до багатьох) у таблиці cars/моделі Car. Тоді потрібно оновити вашу схему наступним чином.

'model-settings' => [  
 \App\Models\v1\User::class => [  
 'collection-schema' => [  
 'fields' => [  
 ['name' => 'id', 'type' => 'string', 'index' => true],  
 ['name' => 'email', 'type' => 'string', 'index' => true, 'optional' => true],  
 ['name' => 'phone', 'type' => 'string', 'index' => trueApp\Models\v1\Car::class => [  
 'collection-schema' => [  
 'fields' => [  
 ['name' => 'id', 'type' => 'string', 'index' => true],  
 ['name' => 'user_id', 'type' => 'string', 'index' => true, 'reference' => 'users.id'],  
 ]  
 ]  
 ]  
 ],

Ваша схема успішно створена.

Підготовка даних для зберігання в Typesense

При використанні Typesense, ваша модель, що підлягає пошуку, повинна визначати метод toSearchableArray.

public function toSearchableArray()  
 {  
 return [  
 'id' => (string) $this->id,  
 'email' => $this->email,  
 'dcoument_url' => $this->Document->docment_url  
 ];  
 }  
}

Як отримати деталі

Реалізуйте API для отримання даних та у вашому контролері User в Laravel спершу створіть клієнт, а потім використовуйте цей клієнт для отримання результатів з сервера Typesense.

public static function getTypsenseClient () {  
 $client = new TypeSenseClient([  
 'api_key' => env('TYPESENSE_API_KEY'),  
 'nodes' => [  
 [  
 'host' => env('TYPESENSE_HOST'),  
 'port' => env('TYPESENSE_PORT'),  
 'protocol' => env('TYPESENSE_PROTOCOL'),  
 ],  
 ],  
 'connection_timeout_seconds' => 2,  
 ]);  

 return $client;  
 }
public static function getUserDetails (Request $request) {  
 $client = self::getTypsenseClient();  

 $searchParameters = [  
 'per_page' => 250,
'sort_by' => 'created_at:asc',  
 'filter_by' => 'id:123&&phone:2642389534',  
 'q' => '[email protected]',  
 'query_by' => 'email', // ви можете передати й інші поля
'include_fields' => '$cars(*,strategy: nest_array)', //nest_array завжди повертає зв'язки у вигляді масиву, а не об'єкта  
 ];  

 $results = $client->collections['users']->documents->search($searchParameters);  
}

Раніше ми реалізували відносини "один до одного" та "один до багатьох" у схемі (scout.php). Щоб отримати результати з пов'язаних таблиць, використовуйте наступний код.

$searchParameters = [  
 'per_page' => 250,  
 'sort_by' => 'created_at:asc',  
 'filter_by' => 'id:123&&phone:2642389534&&$cars(id:*&&car_name:abc)',  
 'q' => '[email protected]',  
 'query_by' => 'email', // ви можете передавати й інші поля  
 'include_fields' => '$cars(*,strategy: nest_array)', //nest_array завжди повертає зв'язки у вигляді масиву, а не об'єкта  
 ];

Отже, ця стаття присвячена інтеграції Typesense з Laravel через драйвер Scout. Я намагався пояснити свої навчання в компактній та зрозумілій формі, але при реальній реалізації не забувайте звертатися до документації.

Перекладено з: Typesense Integration with Laravel

Leave a Reply

Your email address will not be published. Required fields are marked *