# Recherche

:::tip{title="En bref"}
Pagefind indexe les fiches générées au build ; la recherche tourne dans le navigateur, sans serveur. Décision : [ADR 009](/decisions/recherche-pagefind).
:::

## Fonctionnement

| Élément             | Où                                                                                                                                                                                           |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Contenu indexé      | Éléments `data-pagefind-body` : fiches de structure, personne, projet, groupe, thématique                                                                                                    |
| Titre des résultats | `data-pagefind-meta="title"` sur le `<h1>` (`PageHeader`)                                                                                                                                    |
| Filtres             | `data-pagefind-filter="type"` (Laboratoires, Chercheurs, Projets…) et `groupe` sur les structures                                                                                            |
| Construction        | `scripts/instance.mjs build` : `pagefind --site .next-<id>/server/app --output-path public/pagefind/<id>`                                                                                    |
| Interface           | `src/features/search/PagefindSearch.tsx`, page `/recherche` ; l'URL garde la requête (`?q=`)                                                                                                 |
| Classement          | structures 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`) |
| Évaluation          | `pnpm search:eval <instance> <url>` sur `tests/search/<instance>.json` → `data/coverage/<instance>/recherche.md`                                                                             |
| Mesure              | issue 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](/donnees/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

| Option                     | Fonctionnement                                                                           | Pour                                                                                                       | Contre                                                                                             |
| -------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| **Pagefind**               | Index statique construit après le build, à partir du HTML ; recherche dans le navigateur | Aucun serveur, gratuit, déjà utilisé par le site d'audit (Zudoku) ; filtres par `data-pagefind-filter`     | Nécessite des pages prérendues ; réindexation à chaque build ; pas de tolérance aux fautes avancée |
| **Meilisearch**            | Serveur de recherche alimenté en JSON                                                    | Tolérance aux fautes, facettes, synonymes, mise à jour sans rebuild, recherche hybride (vecteurs) possible | Un service à héberger et superviser                                                                |
| **Postgres plein texte**   | Index `tsvector` dans la base déjà prévue                                                | Pas de nouveau service                                                                                     | Pertinence et facettes plus pauvres, configuration du français à soigner                           |
| Elasticsearch / OpenSearch | Choix de scanR                                                                           | Puissant                                                                                                   | Surdimensionné 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.
