mardi, mai 22 2007, 09:41
Ajout de la recherche sur docs.pgfr.org
Par Guillaume Lelarge - PostgreSQL - Lien permanent
Oula, ceux qui ont pigé, pas la peine de vous précipiter, ce n'est pas encore disponible. Pour les autres, un petit résumé... Le site de la documentation française de PostgreSQL contient les manuels des versions 7.4, 8.0, 8.1 et 8.2. Évidemment, avec leurs quelques 700 pages web par manuel, il n'est pas toujours évident de trouver l'information recherchée. Il est toujours possible de passer par Google mais ce n'est pas vraiment simple. J'ai donc profité de la semaine dernière pour incorporer un moteur de recherche puissant mais simple d'utilisation.
Justement, PostgreSQL dispose d'un module contrib proposant la recherche plein texte (très mauvaise traduction de Full Text Indexing, FTI pour les intimes). Ce module, nommé TSearch2, doit être ajouté à une base et permet l'indexation de gros volume de texte. Après avoir compris l'installation et l'utilisation de TSearch2, il ne me restait plus qu'à placer les manuels dans une base PostgreSQL, ajouter le module TSearch2 à cette base et construire une interface pour interroger la base.
La compilation/installation de TSearch2 est simplissime avec les patchs et archives tar de Cédric. En gros, vous récupérez le stemmer français UTF-8, stemmer_utf8_french.tar.gz, que vous déballez dans le sous-répertoire contrib/tsearch2 du répertoire des sources. Récupérez ensuite le premier patch, tsearch_snowball_82, qui est la version compatible avec les derniers stemmers snowball. Appliquez le à partir de la base des sources (un simple « patch -Np0 < tsearch_snowball_82 » suffira). Enfin, récupérez le patch de Cédric ajoutant par défaut le dictionnaire français UTF-8, 61-tsearch-french-utf8.diff. Appliquez-le aussi à partir de la racine des sources. Compilez TSearch2 et installez-le (« make && make install »). Et voilà, c'est terminé. Il ne vous reste plus qu'à exécuter le fichier tsearch2.sql sur votre base et vous disposerez du module pour cette base.
Si vous voulez en plus le dictionnaire ispell, récupérez aussi l'autre archive tar de Cédric, ispell_utf8_french.tar.gz. Par contre, cela nécessitera des modifications dans les tables de configuration de TSearch2, l'installation n'est pas automatique comme avec le stemmer.
L'intégration des documents en base paraît assez simple. Il suffit d'écrire un petit script qui lit le contenu de chaque page et l'intègre dans un champ d'une table spécifique. La table en question, que l'on nommera pages, contient plusieurs champs :
- un id ;
- le nom du fichier ;
- la version du manuel auquel appartient ce fichier ;
- le contenu de ce fichier.
Je vais passer sur les détails. En regardant les mots indexés, je me suis aperçu que je ne pouvais pas intégrer le contenu complet du fichier, y compris une fois débarrassé des balises HTML. Seule une partie de ce fichier a un contenu intéressant... le reste, c'est par exemple le titre du chapitre précédent et suivant (inutile, voire trompeur pendant une recherche). Donc, il a fallu détecter l'endroit exact du contenu réel. Celui-ci est différent pour un chapitre, une partie, une page man, une section, etc. Ceci fait, TSearch2 étant capable de donner un poids plus ou moins fort à des champs différents, j'ai ajouté un champ titre, un champ tags1 (contenant les mots indexés grâce à la balise DocBook firstterm) et un champ tags2 (même chose pour la balise secondterm). J'ai enfin ajouté une dernière colonne de type tsvectors et contenant la vectorisation des quatre champs. Le script d'intégration des documents commence par supprimer les pages déjà enregistrées pour la version du manuel que l'on souhaite intégrer, copie les documents en base après les avoir disséqués, met à jour la colonne de vectorisation et exécute un « VACUUM FULL ANALYZE ». Une fois les quatre versions intégrées, il a fallu construire le script PHP de recherche.
Pour cette page, j'ai utilisé un autre patch de Cédric (décidément
). Il s'agit d'un patch pour wikimedia, transformant les critères de recherche « compréhensibles par un humain » en critères de recherche compréhensibles par TSearch2. Je l'ai donc intégré dans le script de recherche. Une fois ces critères transposés pour TSearch2, il ne reste plus qu'à envoyer la requête au serveur :
SELECT version, url, titre, headline(contenu, q) AS resume, to_char(rank(fti, q)*100, '99.99') AS score
FROM pages, to_tsquery('critère de recherche') AS q
WHERE fti @@ q
ORDER BY rank(fti, q) DESC
Si une version est précisée, la requête filtre aussi par cette version. Je dois avouer que cela remplit bien son oeuvre. Évidemment, il manque certaines choses comme une pagination (avoir 500 résultats sur une même page, c'est long et fastidieux) et une page d'explication sur les critères de recherche. Mais bon, le principal est là.
Le résultat n'est pour l'instant pas disponible. La machine qui héberge docs.pgfr.org héberge un serveur PostgreSQL 8.1, or il me faudrait une version 8.2... et d'autres bases existent sur ce serveur, il ne sera donc pas simple de migrer. En tout cas, ce n'est pas possible actuellement.
un commentaire
Alors ça, si c'est pas du tizingue éhonté...
Ton objectif, en fait, c'est qu'en cherchant la fonctionnalité de recherche, les visiteurs lisent la totalité de la documentation, après quoi ils n'ont plus besoin de cette fonctionnalité.