Wagtailmeili : intégrer un moteur de recherche ultra-rapide à Wagtail

by Maxime Decooman
Meilisearch en quelques mots
Meilisearch est un moteur de recherche open-source ultra-rapide conçu pour créer des expériences de recherche intuitives et agréables. Il a été conçu en mettant l'accent sur l'expérience des développeurs et la facilité d'utilisation.
Caractéristiques principales :
- Rapidité : grâce à son noyau optimisé écrit en Rust.
- Facilité d'utilisation : il propose des valeurs par défaut raisonnables et une API propre et bien documentée. Vous pouvez démarrer avec une configuration minimale.
- Pertinence : Il utilise des règles de classement personnalisables pour affiner la pertinence en fonction des besoins.
- Recherche floue : La tolérance aux fautes de frappe intégrée permet aux utilisateurs de trouver ce qu'ils recherchent, même en cas de fautes d'orthographe mineures.
- Axé sur la recherche : Il excelle dans cette tâche spécifique et n'essaie pas d'être un magasin de données polyvalent ou un moteur d'analyse.
- Open Source et option cloud : Il est entièrement open source (sous licence MIT) et offre également un service en nuage pour l'hébergement géré.
A propos des autres moteurs de recherche
Je vous épargnerai un autre article qui ajoute au bruit. Lisez cet article de meilisearch ou lisez cet extrait qui résume bien leur place dans l'écosystème.
Contrairement à Elasticsearch, qui est un moteur de recherche général conçu pour de grandes quantités de données (par exemple, recherche en arrière-plan), Meilisearch est destiné à fournir des expériences de recherche instantanée performantes destinées aux utilisateurs finaux (par exemple, recherche front-end).
Meilisearch est un choix parfait si vous avez besoin d'un outil simple et facile pour déployer une barre de recherche tolérante aux fautes de frappe. Il offre une capacité de recherche avec préfixes, rend la recherche intuitive pour les utilisateurs et renvoie les résultats instantanément avec une excellente pertinence dès le départ.
Complément idéal pour Wagtail CMS
Elasticsearch n'est pas nécessaire pour de nombreux projets, exigeant plus d'infrastructure que ce dont vous avez réellement besoin. Wagtail supporte nativement la recherche et s'intègre avec OpenSearch et Elasticsearch, mais avoir une autre option comme Meilisearch nous donne une excellenta alternative.
Meilisearch est suffisamment léger pour démarrer sur le même serveur et peut facilement évoluer vers sa propre infrastructure dédiée par la suite ou avec leur offre infonuagique.
Bonjour Wagtailmeili
Il y a environ deux ans, j'ai intégré Meilisearch dans un projet. Afin de l'améliorer et d'ajouter plus de fonctionnalités, j'ai migré cette intégration dans un module opensource, wagtailmeili.
Avant de commencer, j'avais fait une recherche rapide et j'avais trouvé un module appelé wagtail-meilisearch, qui a le même objectif. J'ai essayé de comprendre sa mise en œuvre tout en apprenant la logique sous-jacente de Wagtail. Il s'agit peut-être d'un problème de compétence de ma part, mais je me suis senti bloqué. Il ne répondait pas à tous mes besoins et je devais respecter un délai serré.
J'ai choisi de partir de zéro en utilisant une approche "LEAN". Toutefois, ce projet existant m'a été très utile pour comprendre la logique d'intégration. En fin de compte, ma décision de construire ma propre solution s'est avérée correcte, puisque j'ai livré le projet dans les délais.
Caractéristiques de l'intégration Wagtail
L'intégration utilise fondamentalement l'API RESTful de Meilisearch à travers le client Python fourni par meilisearch.
Dans les paramètres
- Améliorer la pertinence des résultats de recherche en
- Personnalisant les RANKING_RULES
- Personnalisant les STOP_WORDS
- Ne pas indexer certains modèles (SKIP_MODELS)
- Un moyen pratique de ne pas indexer les instances basées sur les attributs (SKIP_MODELS_BY_FIELD_VALUE)
Par défaut, les pages Wagtail qui ne sont pas publiées ne sont pas indexées
WAGTAILSEARCH_BACKENDS = {
"default" : {
"BACKEND" : "wagtailmeili.backend",
"HOST" : config("MEILISEARCH_HOST", "http://127.0.0.1"),
"PORT" : config("MEILISEARCH_PORT", 7700, cast=int),
"MASTER_KEY" : config("MEILISEARCH_MASTER_KEY"),
# "STOP_WORDS" : .... (facultatif, uniquement pour remplacer les valeurs par défaut)
# "RANKING_RULES : ... (facultatif, uniquement pour remplacer les valeurs par défaut)
"SKIP_MODELS" : ["app_label.Model1", "app_label.Model2",],
"SKIP_MODELS_BY_FIELD_VALUE" : {
"wagtailmeili_testapp.MoviePage" : {
"field" : "status",
"value" : "archived",
},
},
# ...
}
}
Dans vos modèles
- Dans un modèle spécifique, vous pouvez :
- Définir des attributs triables
- Définir des règles de classement spécifiques
class MySuperPage(Page) :
"""Une Super Page pour faire des choses incroyables."""
sortable_attributes = [
"published_last_timestamp",
# ...
]
ranking_rules = [
"published_last_timestamp:desc",
# ...
]
Template Tag filter
Pas encore documenté car je suis encore en train de porter certaines fonctionnalités du projet initial.
{% load meilisearch %}
{% get_matches_position result %}
Searching
Pour des raisons pratiques, j'ai ajouté un gestionnaire pour une page Wagtail ou un modèle Django. Vous pouvez soit définir la recherche avec un appel backend standard :
# par exemple
search_backend = get_search_backend("default")
# puis faire votre recherche
search_backend.search(...)
Ou à partir du modèle en utilisant un des gestionnaires
from wagtailmeili.manager import MeiliSearchPageManager
from wagtailmeili.manager import MeiliSearchModelManager
# dans votre classe de modèle de page MyPage, par exemple, ajoutez ceci
objects = MeiliSearchPageManager()
# utilisera le backend Meilisearch
MyPage.objects.search(....)
Paramètres de recherche
# vous pouvez configurer vos paramètres de recherche, l'argument "opt_params"
# Imaginons que vous avez des opt_params par défaut comme suit
opt_params = {
"page" : page_number,
"hitsPerPage" : 10,
"facets" : ["topics.id", "commodities.id"]
}
# vous pouvez ajouter plus tard un filtre comme celui-ci par exemple
opt_params["filter"] = search_filters
# et les utiliser dans votre recherche
results = MyPage.objects.search(query, opt_params=opt_params).get()
Mises à jour des index
Pas de grande magie ici car cela utilise le mécanisme standard de Wagtail (signaux de Django). Lorsque vous créez une instance d'un modèle indexé, elle sera ajoutée automatiquement et mise à jour lorsque vous faites un changement. Si vous avez besoin de mettre à jour l'index depuis la ligne de commande, il vous suffit d'utiliser la commande standard :
python manage.py update_index
Stratégie de mise à jour
La stratégie de mise à jour est une stratégie d'échange (swap). Le nouvel index est construit avec un suffixe _new ajouté à son nom. Il est ensuite utilisé pour échanger l'ancien index. L'ancien index est ensuite supprimé. Dans la plupart des cas, je ne pense pas que les performances seront un problème. Il vaut mieux passer du temps sur les fonctionnalités d'abord. On verra si la demande est là.
Nouvelle commande
Si nécessaire pendant le développement, vous pouvez supprimer tous les index, j'ai ajouté une nouvelle commande : ```python python manage.py meilisearch_delete_all_indexes ````
Prochaines étapes
Wagtailmeili offre suffisamment de fonctions de recherche de base pour vous permettre de démarrer. Cependant, ce n'est que le début. Un projet de démonstration avec un frontend basique (HTMX et AlpineJS) sera mis en place pour montrer les possibilités et permettre de bricoler avec.
Avant la version 1.0, je recommande de corriger la version dans vos exigences car des choses peuvent se casser (voir le changelog avant de mettre à jour).
Feuille de route avant 1.0.0 (non triée)
- ✅ Ajout de tests (fait)
- Explorer Meilisearch et apporter plus de ses fonctionnalités pour Wagtail. ( Je n'écrirai pas le mot "AI" dans ce billet... 👀)
- Obtenir une implémentation allégée (et donner quelques idées pour Wagtail)
- Donner plus d'amour au projet démo avec un frontend
- Meilleure documentation basée sur le projet démo
- Une recette pour l'internationalisation
Vous aimez ? Donnez-lui une étoile et suivez le projet sur