Utiliser Zend_Search_Lucene pour créer son propre moteur de recherche !

Le Zend Framework contient un composant permettant de créer rapidement et simplement son propre moteur de recherche ! Ce composant nommé Zend_Search_Lucene est un portage, du projet Java du même nom, totalement écrit en PHP5.
Ce composant est autonome et ne demande aucune architecture spécifique. De ce fait il peux servir pour tout nouveau projet ou s’intégrer dans un projet existant. Aucune base de données n’est nécessaire. De plus les index peuvent être utilisés aussi bien avec Zend_Search_Lucene, qu’avec tout autre portage de Lucene (Attention toutefois, tous les encodages ne sont pas supportés !)
Il supporte différents encodages grâce à l’utilisation de différents analyseurs, mais pas l’UTF-8 par défaut, comme PHP me direz-vous :p
Contrairement au reste de la documentation et des autres composants du Zend Framework, le fonctionnement de Zend_Search_Lucene n’est pas des plus explicites.
Dans cet article nous verrons donc, comment utiliser Zend_Search_Lucene pour construire un index, construire les requêtes de recherches et enfin afficher les résultats dans une page. Le tout en UTF-8 bien évidemment.
Configuration du module
Tout d’abord, commençons par modifier le comportement par défaut du composant, en lui passant un analyseur compatible avec l’UTF8, les caractères numériques mais aussi insensible à la casse.
Zend_Search_Lucene_Analysis_Analyzer::setDefault( new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive() );
L’index de recherche
Avant de pouvoir effectuer la moindre recherche, il faut d’abord construire l’index qui nous servira de base pour la recherche.
La construction de l’index permet d’importer des documents, eux-mêmes composés de champs. Ce sont les champs qui permettent à Zend_Search_Lucene de retrouver quel document doit ressortir dans les résultats de recherche.
$index = Zend_Search_Lucene::create( APPLICATION_PATH . '/data/lucene' );
Une fois l’index créé, nous devons inclure des documents à celui-ci, il ne faut pas oublier de forcer l’encodage des champs en UTF-8, afin qu’il soit concordant avec l’encodage de l’analyseur.
Chaque champs du document représente différents type, permettant ainsi de découper les résultats sous plusieurs formes en s’adaptant à la structure de l’application. On y stocke par exemple l’URL de la page à voir, son titre, son auteur…
Les différents types de champs possibles sont :
- Keyword : Les données sont indexées et stockées, mais pas tokenisées. Par exemple pour l’identifiant, l’url…
- UnIndexed : Les données sont stockées mais pas indexées. Par exemple pour l’aperçu du contenu, la date de création…
- UnStored : Les données ne sont pas stockées, mais indexées et tokenisées. Par exemple pour le contenu du document…
- Text : Les données sont indexées, stockées et tokenisées. Par exemple pour le titre, l’auteur…
- Binary : Les données ne sont pas indexées, ni tokenisées, mais sont stockées en binaire. Par exemple pour l’image…
Les données stockées peuvent être affichées dans les résultats de recherche. Les données indexées permettent de trier les résultats de recherche par ordre d’importance. Les données tokenisées permettent de découper le contenu en mots clés pour la recherche.
$document = new Zend_Search_Lucene_Document(); $document->addField( Zend_Search_Lucene_Field::keyword( 'idPost', 52, 'utf-8' ) ); $document->addField( Zend_Search_Lucene_Field::unIndexed( 'preview', 'contenu contenu2...', 'utf-8' ) ); $document->addField( Zend_Search_Lucene_Field::unStored( 'content', 'contenu contenu2 contenu3 contenu4', 'utf-8' ) ); $document->addField( Zend_Search_Lucene_Field::text( 'title', 'Titre de mon résultat', 'utf-8' ) ); $index->addDocument( $document );
Jusqu’ici nous avons ajouté des documents, mais aucune modification n’est apporté à l’index tant que la méthode commit() n’est pas appelée. Il est donc tout à fait possible de boucler des éléments d’une table pour les convertir en document pour l’index. En cas de mises à jour successives, la méthode optimize() permet d’optimiser l’index.
Il existe bien évidemment d’autres types de documents permettant d’importer directement des fichiers Word 2007, Powerpoint 2007 ou encore Excel 2007 dans l’index.
Attention, on ne peux utiliser de champs nommé « id », celui-ci correspond à l’id du document dans l’index.
$index->commit(); $index->optimize();
Et voilà, l’index de recherche est créé, et contient des documents. Il est maintenant possible d’effectuer des requêtes sur cet index et d’en retourner les résultats.
Requêtes et affichage des résultats
Afin d’interroger l’index, il suffit de l’ouvrir avec la méthode appropriée. Une fois l’index ouvert, il suffit simplement de passer une variable contenant la recherche dans la méthode find() qui retourne les résultats.
$index = Zend_Search_Lucene::open( APPLICATION_PATH . '/data/lucene' ); $this->view->results = $index->find( $q ); // $q = 'test recherche'; $page = Zend_Paginator::factory( $this->view->results ); $page->setPageRange( 10 ); $page->setCurrentPageNumber( $this->_getParam('page', 1) ); $page->setItemCountPerPage( 20 ); $this->view->results = $page;
Comme on peux le constater, le composant est compatible avec le paginator, ce qui permet de paginer simplement les résultats comme n’importe quel autre sources !
Ceci est une petite approche rapide, mais qui permet déjà d’instaurer rapidement un moteur de recherche sur votre site.
Je découvre ce blog je vois que sincèrement c’est très intéressant!!, et je ne peux que partager cet avis
vous avez raison oui