Après le live search, et la recherche prédictive, ce troisième volet de notre série d’articles sur les formulaires de recherche est consacré à la recherche par facettes. La recherche à facettes a ceci de particulier que l’implémentation en fait aussi bien un mode de recherche que de navigation, et c’est à ce double emploi que nous allons nous intéresser aujourd’hui.

Histoire d’illustrer mon propos, je vous propose un cas en grandeur réelle. Il s’agira de mettre en place une navigation par facettes pour le Digg like Fuzz, dont la navigation pourrait être améliorée (et non, ce billet n’a en aucun cas été sponsorisé par Éric).

Il en va de la recherche comme du fromage, c’est meilleur lorsque c’est bien affiné

L’objectif de la recherche par facettes est de réduire le nombre de résultats retournés en ajoutant des critères de recherche aux résultats précédemment obtenus. Ces critères de recherche sont générés dynamiquement en fonction de ces mêmes résultats, afin de supprimer les filtres non pertinents.

La recherche par facettes ne rentre donc pas dans le cadre des formulaires de recherche avancée, en ce que les critères ne précèdent pas la recherche. On part de “tout” pour arriver à “quelques uns”.

Où utiliser un système de recherche par facettes

Le système de navigation par facettes ne s’adapte pas à n’importe quel site. Pour un Digg like de la taille de Fuzz, il serait même presque sous dimensionné. Il est en revanche presque indispensable sur les sites proposant des items définis par un très grand nombre de caractéristiques.

  • Site de e-commerce.
  • Sites d’offres d’emploi.
  • Annonces immobilières (et annonces en tout genre).

Bien choisir son fromage ses critères de sélection

Le plus difficile dans la conception d’une recherche à facettes est le choix des critères de filtrage. Si mettre les points d’entrée du site ou de l’application paraît tout à fait normal, le fonctionnel plus fin jouera également un rôle important.

Les facettes peuvent être simples – c’est à dire exclusives – ou multiples. Dans le premier cas, on ne filtrera que sur une valeur pour chaque critère de recherche, dans le second cas, on pourra appliquer plusieurs valeurs à un même critère. On appliquera alors un AND : retourner toutes les valeurs pour lesquelles le critère A a la valeur X ET la valeur Y.

Dans le cas de Fuzz, on ajoutera le filtrage sur :

  • Catégories : facette simple.
  • Tags : facette multiple.
  • Utilisateurs ayant proposé des dépêches : facette simple.

Mettre les utilisateurs dans les critères de filtrage peut sembler un peu superfétatoire. Il est pourtant cohérent avec le fonctionnement réel des Digg like. En faisant remonter les utilisateurs qui publient le plus de dépêches en haut, on incite ceux n’en faisant pas partie à en proposer plus afin d’apparaître dans ce classement.

Je n’ai pas permis de filtrer sur plusieurs catégories, car Fuzz ne permet d’en assigner qu’une seule par dépêche. On peut en revanche proposer plusieurs tags, et là encore, le fonctionnement va inciter les soumissionnaires à les utiliser.

Et si on passait à l’implémentation ?

Côté client, il va nous falloir rajouter deux blocs. Le premier est un bloc de filtrage par utilisateurs, puisque Fuzz dispose déjà d’un bloc de filtrage par catégorie et par tag. Le second est un bloc résumant les critères de filtrage ajoutés et permettant de les retirer en cas de besoin.

exemple de navigation par facettes

Le comportement est simple :

  • Quand l’utilisateur ajoute une facette simple, on supprime le bloc correspondant de la page.
  • Chaque facette sélectionnée est ajoutée au bloc de navigation.
  • Quand l’utilisateur supprime une facette, on réaffiche le bloc correspondant sur la page.

Côté serveur, les choses sont un peu plus complexes, car ce mode de recherche est très coûteux en ressources. Il existe plusieurs manières de faire, aucune des deux n’étant parfaite. La première va entraîner un surcroît de requêtes SQL, la seconde plus de calcul côté frontend.

La première est certainement la plus simple à mettre en place. Chaque fois qu’un visiteur va ajouter ou supprimer une facette, on crée la requête SQL adaptée et on l’exécute. Certains framework comme Ruby on Rails possèdent un système de cache des résultats des méthodes appelées dans les classes avec les arguments d’appel, comme cachesactionswith_params. Couplé à un serveur memcache, ce dernier va considérablement accélérer les recherches sans tirer sur les disques durs.

L’autre méthode m’a été expliquée par Alexandre Heimburger. On va mettre les résultats de la première requête en cache dans un fichier XML, que l’on pourra également placer en mémoire afin de gagner sur les accès disques. Chaque fois que l’utilisateur ajoutera une facette, on parcourra le XML afin d’en extraire les noeuds correspondants.

Et voilà, that’s all folks, comme dirait Buggs Bunny. La prochaine fois, nous parlerons de la mise en place d’un formulaire de recherche avancée, et croyez-moi, il y a des choses à dire !

Perry the Platypus wants you to subscribe now! Even if you don't visit my site on a regular basis, you can get the latest posts delivered to you for free via Email: