Architecture

Recherche

En bref

Pagefind indexe les fiches générées au build ; la recherche tourne dans le navigateur, sans serveur. Décision : ADR 009.

Fonctionnement

ÉlémentOù
Contenu indexéÉléments data-pagefind-body : fiches de structure, personne, projet, groupe, thématique
Titre des résultatsdata-pagefind-meta="title" sur le <h1> (PageHeader)
Filtresdata-pagefind-filter="type" (Laboratoires, Chercheurs, Projets…) et groupe sur les structures
Constructionscripts/instance.mjs build : pagefind --site .next-<id>/server/app --output-path public/pagefind/<id>
Interfacesrc/features/search/PagefindSearch.tsx, page /recherche ; l'URL garde la requête (?q=)
Classementstructures en tête (5 premières), puis le reste ; listes de rattachement exclues (data-pagefind-ignore) ; titres et sigles pondérés ; prime aux pages courtes atténuée (pageLength: 0.2)
Évaluationpnpm search:eval <instance> <url> sur tests/search/<instance>.json → data/coverage/<instance>/recherche.md
Mesureissue de chaque recherche → /api/telemetry (compteur Prometheus) et Matomo trackSiteSearch

Volumes : 12 209 pages et 119 873 mots indexés pour Paris-Saclay, 2 417 pages pour Paris 1.

Limites et suites

  • Les liens de résultats retirent l'extension .html des fichiers indexés pour retrouver la route Next (toRoute).
  • Résultat des requêtes de référence : 17/20 (Saclay), 19/20 (Paris 1) ; les échecs portent sur des structures sans présentation (couverture).
  • Pas de tolérance aux fautes ni de synonymes.
  • La recherche d'expertise « qui travaille sur… » s'appuie sur les domaines scanR et les mots-clés HAL présents dans les fiches ; une recherche sémantique supposerait Meilisearch avec vecteurs.

Options comparées

OptionFonctionnementPourContre
PagefindIndex statique construit après le build, à partir du HTML ; recherche dans le navigateurAucun serveur, gratuit, déjà utilisé par le site d'audit (Zudoku) ; filtres par data-pagefind-filterNécessite des pages prérendues ; réindexation à chaque build ; pas de tolérance aux fautes avancée
MeilisearchServeur de recherche alimenté en JSONTolérance aux fautes, facettes, synonymes, mise à jour sans rebuild, recherche hybride (vecteurs) possibleUn service à héberger et superviser
Postgres plein texteIndex tsvector dans la base déjà prévuePas de nouveau servicePertinence et facettes plus pauvres, configuration du français à soigner
Elasticsearch / OpenSearchChoix de scanRPuissantSurdimensionné pour quelques milliers de fiches

Recommandation

  • Version 1 : Pagefind (en place), sur les fiches prérendues depuis data/public. Les volumes, quelques centaines de structures et quelques milliers de personnes, sont dans sa zone de confort.
  • Passer à Meilisearch si l'un de ces besoins apparaît :
    • mise à jour en continu sans reconstruction ;
    • tolérance aux fautes exigée ;
    • recherche d'expertise sémantique (« qui travaille sur… ») par vecteurs.

Le moteur est déclaré dans research.config.ts (search.engine) ; seul pagefind est implémenté. Un second moteur demandera une interface commune côté interface de recherche.

Dans tous les cas, la recherche sert les entités de la vitrine. Pour les publications, elle renvoie vers HAL et scanR.