Les outils de recherche ElasticSearch et Algolia ont gagné en popularité dans la communauté Laravel ces dernières années en tant qu’outils puissants pour indexer et rechercher vos données. Ben Corlett a fait un travail fantastique en présentant ElasticSearch à Laracon Eu 2014, et j’ai écrit une demande d’extraction à Laravel.com en introduisant l’indexation basée sur ElasticSearch pour les documents en 2015. Mais avant que mon PR ne soit fusionné, les gens d’Algolia l’ont pris et mis à jour pour utiliser à la place Algolia (plus rapide et avec une meilleure interface utilisateur !), et c’est ce que vous verrez aujourd’hui si vous recherchez la documentation de Laravel.
Si vous jetez un coup d’œil à ma demande d’extraction ou à la leur, vous verrez que ce n’est pas une mince tâche d’intégrer la recherche en texte intégral dans votre site. Algolia a depuis publié un produit gratuit appelé Algolia DocSearch qui facilite l’ajout d’un widget de recherche Algolia aux pages de documentation. Mais pour tout le reste, vous êtes toujours coincé à écrire l’intégration vous-même, c’est-à-dire jusqu’à maintenant.
Présentation de Laravel Scout
Scout est une solution de recherche en texte intégral basée sur un pilote pour Eloquent. Scout facilite l’indexation et la recherche du contenu de vos modèles Eloquent ; actuellement, il fonctionne avec Algolia et ElasticSearch, mais Taylor a demandé des contributions de la communauté à d’autres services de recherche en texte intégral.
Scout est un package Laravel distinct, comme Cashier, que vous devrez intégrer à Composer. Nous allons ajouter des traits à nos modèles qui indiquent à Scout qu’il doit écouter les événements déclenchés lorsque des instances de ces modèles sont modifiées et mettre à jour l’index de recherche en réponse.
Jetez un oeil à cette syntaxe pour la recherche en texte intégral, pour trouver n’importe quel Review
avec le mot Llew
dedans :
Review::search('Llew')->get();
Review::search('Llew')->paginate(20);
Review::search('Llew')->where('account_id', 2)->get();
Tout cela avec très peu de configuration. C’est une belle chose.
Installation de Scout
Tout d’abord, insérez le package (une fois qu’il est en ligne et sur une application Laravel 5.3):
composer require laravel/scout
Ensuite, ajoutez le fournisseur de services Scout (Laravel\Scout\ScoutServiceProvider::class
) au providers
section de config/app.php
.
Nous voudrons mettre en place notre configuration Scout. Courir php artisan vendor:publish
et collez vos identifiants Algolia dans config/scout.php
.
Enfin, en supposant que vous utilisez Algolia, installez le SDK Algolia :
composer require algolia/algoliasearch-client-php
Marquage de votre modèle pour l’indexation
Maintenant, allez à votre modèle (nous utiliserons Review
, pour une critique de livre, pour cet exemple). Importez le Laravel\Scout\Searchable
trait. Vous pouvez définir quelles propriétés peuvent être recherchées à l’aide de la toSearchableArray()
méthode (par défaut, la mise en miroir toArray()
), et définissez le nom de l’index du modèle à l’aide de la searchableAs()
méthode (il s’agit par défaut du nom de la table).
Une fois que nous avons fait cela, vous pouvez aller consulter votre page d’index Algolia sur leur site Web; lorsque vous ajoutez, mettez à jour ou supprimez Review
enregistrements, vous verrez la mise à jour de votre index Algolia. Juste comme ça.
Recherche dans votre index
Nous avons déjà jeté un coup d’œil à cela, mais voici une actualisation de la façon de rechercher :
// Get all records from the Review that match the term "Llew"
Review::search('Llew')->get();
// Get all records from the Review that match the term "Llew",
// limited to 20 per page and reading the ?page query parameter,
// just like Eloquent pagination
Review::search('Llew')->paginate(20);
// Get all records from the Review that match the term "Llew"
// and have an account_id field set to 2
Review::search('Llew')->where('account_id', 2)->get();
Qu’est-ce qui ressort de ces recherches ? Une collection de modèles éloquents, réhydratés à partir de votre base de données. Les identifiants sont stockés dans Algolia, qui renvoie une liste d’identifiants correspondants, puis Scout extrait les enregistrements de la base de données pour ceux-ci et les renvoie sous forme d’objets Eloquent.
Vous n’avez pas un accès complet à la complexité de SQL where
commandes, mais il gère un cadre de base solide pour les vérifications de comparaison comme vous pouvez le voir dans les exemples de code ci-dessus.
Files d’attente
Vous pouvez probablement deviner que nous envoyons maintenant des requêtes HTTP à Algolia à chaque requête qui modifie des enregistrements de base de données. Cela peut ralentir les choses très rapidement, vous pouvez donc vous retrouver à vouloir mettre ces opérations en file d’attente, ce qui, heureusement, est simple.
Dans config/scout.php
ensemble queue
pour true
afin que ces mises à jour soient définies pour être indexées de manière asynchrone. Nous examinons maintenant la “cohérence éventuelle” ; vos enregistrements de base de données recevront les mises à jour immédiatement, et les mises à jour de vos index de recherche seront mises en file d’attente et mises à jour aussi rapidement que votre file d’attente le permet.
Cas spéciaux
Couvrons quelques cas particuliers.
Effectuer des opérations sans indexation
Que faire si vous souhaitez effectuer un ensemble d’opérations et éviter de déclencher l’indexation en réponse ? Enveloppez-les simplement dans withoutSyncingToSearch()
méthode sur votre modèle :
Review::withoutSyncingToSearch(function () {
// make a bunch of reviews, e.g.
factory(Review::class, 10)->create();
});
Déclencher manuellement l’indexation via le code
Disons que vous êtes maintenant prêt à effectuer les index, maintenant qu’une opération en bloc a été effectuée avec succès. Comment?
Ajoutez simplement searchable()
à la fin de toute requête Eloquent et il indexera tous les enregistrements trouvés dans cette requête.
Review::all()->searchable();
Vous pouvez également choisir de limiter la requête à ceux que vous souhaitez indexer, mais il convient de noter que l’indexation insérera de nouveaux enregistrements et mettra à jour les anciens enregistrements, il n’est donc pas mauvais de la laisser s’exécuter sur certains enregistrements qui peuvent déjà être indexés.
Cela fonctionnera également sur une relation :
$user->reviews()->searchable();
Vous pouvez également désindexer tous les enregistrements avec le même type de chaînage de requêtes, mais en utilisant simplement unsearchable()
plutôt:
Review::where('sucky', true)->unsearchable();
Déclencher manuellement l’indexation via CLI
Il y a une commande Artisan pour ça.™
php artisan scout:import App\\Review
Cela va écraser tout le Review
modèles et indexez-les tous.
Conclusion
C’est ça! Avec presque aucun travail, vous avez maintenant une recherche complète en texte intégral en cours d’exécution sur vos modèles Eloquent.