La recherche Typesense avec Symfony
Dans une application Web avec Symfony, la question de la mise en place d’un moteur de recherche intelligent est souvent mise sur la table. Dans cet article, on vous présente l’outil de recherche Typesense.
Il est toujours pratique de disposer d’un outil qui permet de «trouver simplement» les données qui sont mises à disposition par l’outil.
Et puis, Google le fait bien, alors ça doit être facile non 😉 ?
Dès que l’on parle de recherche de données, les choses se corsent peu à peu.
En général, l’organisation des données est effectuée grâce à une base de données (MySQL, PostgreSQL) et exploitée grâce à un ORM tel que Doctrine. La mise en place d’un moteur de recherche avec ces outils se retrouve souvent limitée à la création de recherches complexes et peu performantes, qui ne donnent pas satisfaction.
De vrais outils d’indexation et de recherche dans votre application Web
Il existe un certain nombre de solutions permettant d’indexer puis de rechercher dans vos données.
Ces outils sont le complément de votre Système de base de données. Ils offrent des performances supérieures et des fonctionnalités supplémentaires, comme par exemple :
- des mécanismes de recherche à facettes
- des mécanismes de recherche approchante (pour trouver malgré une faute d’ortographe par exemple)
- des systèmes de pondération et de score des résultats
Dans ce domaine, Elasticsearch est un outil de disponible depuis de nombreuses années. Cependant, une solution basée sur Elasticsearch peut être assez «lourde» à mettre en place (en temps et en mémoire consommée), et certains aspect de la solution la rendent complexe à mettre en oeuvre. Le Bundle FOSElasticaBundle permet cependant d’intégrer facilement cette solution dans vos projets.
Utiliser Typesense avec Symfony
Typesense est un moteur de recherche Open Source qui offre les fonctionnalités attendues dans ce domaine.
L’écosystème Symfony permet facilement de mettre en place Typesense dans votre projet, à l’aide du Bundle ACSEO/TypesenseBundle.
Que propose le Bundle ACSEO/TypesenseBundle
- Définition des données à indexer par paramétrage
- Commandes de création et d’indexation des données de Doctrine vers Typesense
- Listener Doctrine pour maintenir les données de Typesense à jour
- Services de recherche des données dans Typesense
- Récupération des résultats de recherche bruts ou sous la forme d’Objets Doctrines hydratés
Mettre en place et utiliser le Bundle (en 5 minutes chrono)
⚠️ Les informations ci-dessous sont tirées de la documentation officielle du Bundle, n’hésitez pas à y jeter un oeil pour être parfaitement à jour.
Installation du Bundle
L’installation se fait de façon assez classique, à l’aide de composer
.
$ composer require acseo/typesense-bundle
Une fois la dépendance installée, il ne vous reste plus qu’à activer le Bundle.
<?php
// config/bundles.php
return [
ACSEO\TypesenseBundle\ACSEOTypesenseBundle::class => ['all' => true],
Configuration du Bundle
La configuration du Bundle permet de faire le lien entre vos Entités Doctrine et ce que vous souhaitez indexer dans Typesense
# .env
TYPESENSE_URL=localhost:8108
TYPESENSE_KEY=123
# config/packages/acseo_typesense.yml
acseo_typesense:
# Typesense host settings
typesense:
host: '%env(resolve:TYPESENSE_URL)%'
key: '%env(resolve:TYPESENSE_KEY)%'
# Collection settings
collections:
books: # Typesense collection name
entity: 'App\Entity\Book' # Doctrine Entity class
fields:
id: # Entity attribute name
name: entity_id # Typesense attribute name
type: primary # Attribute type
title:
name: title
type: string
author:
name: author
type: object # Object conversion with __toString()
author.country:
name : author_country # equivalent of $book->getAuthor()->getCountry()
type: string
genres:
name : genres
type: collection # Convert ArrayCollection to array of strings
publishedAt:
name : published_at
type: datetime
default_sorting_field: published_at # Default sorting field. Must be primary, int32 or float
Utilisation de Typsense
Création de l’index et indexation des données initiales
Le Bundle est livré avec des commandes utiles pour la création des collections Typsense et l’indexation initiales des données
# Creation collections structure
$ php bin/console typesense:create
# Populate collections with Doctrine entities
$ php bin/console typesense:populate
Recherche de documents
Le Bundle créée dynamiquement des finders utilisables dans vos Services ou vos Controlleurs : typesense.finder.collection_name
# config/services.yaml
services:
App\Controller\BookController:
arguments:
$bookFinder: '@typesense.finder.books'
<?php
// src/Controller/BookController.php
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use ACSEO\TypesenseBundle\Finder\TypesenseQuery;
//
class BookController extends AbstractController
{
private $bookFinder;
public function __construct($bookFinder)
{
$this->bookFinder = $bookFinder;
}
public function search()
{
$query = new TypesenseQuery('Symfony', 'title');
// Get Doctrine Hydrated objects
$results = $this->bookFinder->query($query)->getResults();
// dump($results)
// array:2 [▼
// 0 => App\Entity\Book
// 1 => App\Entity\Book
//]
// Get raw results from Typesence
$rawResults = $this->bookFinder->rawQuery($query)->getResults();
// dump($rawResults)
// array:2 [▼
// 0 => array:3 [▼
// "document" => array:4 [▼
// "author" => "Fabien Potencier"
// "id" => "100"
// "published_at" => 1443744000
// "title" => "Symfony 5: The Fast Track"
// ]
// "highlights" => array:1 [▶]
// "seq_id" => 4
// ]
// 1 => array:3 [▼
// "document" => array:4 [▶]
// "highlights" => array:1 [▶]
// "seq_id" => 6
// ]
// ]
}
Typesense : la bonne alternative à Elasticsearch
Comme vous le voyez, il est très facile de pouvoir utiliser un moteur de recherche puissant dans vos projets Symfony.
Typesense constitue une très bonne alternative, moins gourmande et moins complexe à Elasticsearch, et couvre de nombreux besoins en matière d’indexation et de recherche de données.