/extension/myblog/design/myblog/stylesheets/white.css
/extension/myblog/design/myblog/stylesheets/black.css

Select your style :

A la une // Les blogs sur le développement Web, l'oenologie, Montpellier, etc...

eZ Find et ses utilisations alternatives : Faire un nuage de tags

eZ Find est une extension native d'eZ Publish, maintenant disponible dans les diverses installations du CMS. Mon précédent billet donne une courte définition du fonctionnement d'eZ Find, de son couplage avec Solr, et de sa relation avec les datatypes.

eZ Find est généralement présenté et vendu comme un moteur de recherche, et les utilisateurs (et développeurs) peuvent donc s'attendre à un mécanisme du type :

  • Je saisie une expression libre
  • J'envoie ma recherche
  • J'obtiens une liste de résultat, et j'applique quelques tris (alphabétique, dates, pertinence) et quelques filtres disponibles (par rubriques, par facettes, etc.)

Cependant, le cadre d'exploitation d'eZ Find est plus vaste que ce schéma fonctionnel. Ce billet décrit un cas d'utilisation certes relativement inutile mais signification d'une utilisation alternative d'eZ Find : construire un nuage de tags.

A partir d'un exemple simple, on peut facilement en déduire d'autres cas d'utilisation qui facilitent énormément le développement de certains projets, comme par exemple les agrégateurs de contenus, les portails et autres mécanismes de navigations complexes dans un catalogue.

Comment construire un nuage de tags sur eZ Publish ?

La seule méthode un peu optimisée et fonctionnelle de procéder actuellement est l'utilisation d'un opérateur de template qui explore la base de données, et notamment la table ezkeyword. Le package ezwebin propose l'opérateur eztagcloud, qui est facile à déployer et à utiliser.

  • Voici un exemple d'appel de l'opérateur dans un template
<div>
   {eztagcloud( hash( 'class_identifier', 'billet', 'parent_node_id', 2 ) )}
</div>
 

Avantages de l'opérateur

Les fonctions fetch natives ne permettent pas de lister un ensemble de keywords en fonction des paramètres utiles (subtree, classes, etc.), c'est donc la seule façon "économique" et "optimisée" de procéder. Les opérateurs permettent souvent aux développeurs eZ Publish avancés d'optimiser certains traitements, en économisant le nombre de requêtes SQL par exemple, ou en facilitant certains algorithmes laborieux à transposer avec le langage de template (par exemple le calcul des pourcentages des styles CSS inline dans cet opérateur)

Inconvénients de l'opérateur

L'écriture de ce type d'opérateur est peu accessible aux développeurs occasionnels, et la manipulation du SQL est une pratique dangereuse si le modèle de données eZ Publish est mal maîtrisé (prise en compte des versions, des visibilités, des langues, des droits...). Par ailleurs cet opérateur encapsule la logique algorithmique du calcul des pourcentages transmis au "font-size" en style inline. Les amoureux du CSS full externe, ou de l'accessibilité devront donc adapter cet opérateur à leur besoin.

Comment construire un nuage de tags avec eZ Find ?

Comprendre le concept de facettes

Derrière ce terme "géométrique" se cache un concept finalement assez simple et naturel, que l'on pourrait appeler : "groupement des résultats pour un champs", à savoir :

  • Supposons qu'un résultat de recherche contienne 100 billets
  • Sur ces 100 billets, on peut lister 20 mots clés distincts associés
  • Parmi ces 20 mots clés, le mot clés A est associé à 10 billets, le mot clés B est associé à 5 billets, et ainsi dessuite

On peut transposer cet exemple sur tous les attributs et meta données d'une classe (name, dates, auteur, attribut quelconque), et même obtenir N listes de facettes sur N attributs et méta différents

Construite le nuage de mots clés avec des facettes

Cet exemple de code montre comment construire sa requête eZ Find, récupérer les facettes résultantes sur l'attribut "tags" de type "keywords", et gérer le poids des keywords en fonction d'un algorithme simplifié (j'ai un peu triché sur cet aspect, puisque ce n'est pas l'objet de la démonstration).

{def $search_keywords=fetch( ezfind , search,
      hash( query , '',
        'facet', array( 
            hash('field', 'billet/tags', 'sort', 'alpha', 'limit', 100 )),
        'class_id', array('billet'),
        'filter', array('not', 'billet/tags:""'),
        'subtree_array', array(2)
        ))}
    
{def $search_extras_keywords=$search_keywords['SearchExtras']}
{def $search_count_keywords=$search_keywords['SearchCount']}
 
<li id="blog_block_{$bloc_count}" class="colonne_block">
   <h1>Tags ezfind :</h1>
    
    <div class="tagclouds {$current_css}">
    {foreach $search_extras_keywords.facet_fields[0].nameList as $facetID =&gt; $name}
                
        {def $keyword_count = $search_extras_keywords.facet_fields[0].countList[$facetID]}
        {def $percent = $keyword_count|div( $search_count_keywords )|mul( 200 )|floor|sum( 100 ) }
            <a href={concat( $root_blog_node.url_alias, '/(tag)/', $name )|ezurl()} style="font-size: {$percent}%" title="{$keyword_count} billets taggés '{$name}' // ">{$name|wash()}</a>, 
        {undef $percent}
 
    {/foreach}
 
    </div>
</li>
{undef $search_extras_keywords $search_keywords $search_count_keywords}
 

Quelques astuces & clés de compréhensions

  • La recherche sur une chaine vide (query , '') est une technique permettant d'explorer l'ensemble des contenus indexés, en appliquant uniquement les filtres et limitations utiles (class_id, subtree_array par exemple)
  • L'opérateur 'NOT' n'est pas natif et nécessite un petit 'hack' proposé par Bruce Morrison, qui sera sans doute disponible dans les futures versions d'eZ Find
  • Par défaut les facettes sur des datatypes 'keywords' sont présentés en minuscule. Ce n'est pas un bug, mais une fonctionnalité visant à homogénéiser la casse sur les syntaxes similaires (eZ Publish, ez Publish, Ez Publish, etc.). Cependant lorsqu'on est confiant dans la qualité de sa saisie (puisqu'on utilise une extension d'autocomplétion par exemple), il peut être souhaitable de ne pas forcer l'utilisation du minuscule. Pour cela il faut désactiver le filtre solr.LowerCaseFilterFactory dans le fichier /extension/ezfind/java/solr/conf/schema.xml
<!-- eZ Find: This field type is dedicated to ez publish keywords.  --> 
<fieldtype name="keyword" class="solr.TextField" positionIncrementGap="100"> 
     <analyzer type="index"> 
       <tokenizer class="solr.PatternTokenizerFactory" pattern=", *" /> 
       <filter class="solr.TrimFilterFactory" />               
       <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/> 
       <!--<filter class="solr.LowerCaseFilterFactory"/>--> 
       <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> 
     </analyzer> 
     <analyzer type="query"> 
       <tokenizer class="solr.PatternTokenizerFactory" pattern=", *" /> 
       <filter class="solr.TrimFilterFactory" /> 
       <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> 
       <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/> 
       <filter class="solr.LowerCaseFilterFactory"/> 
       <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> 
     </analyzer> 
</fieldtype>
 

Que boire avec ce billet ?

Domaine Cauhapé - La Canopée - Blanc Sec 2006

Région : Sud Ouest
Appellation : Jurançon
Domaine : Domaine Cauhapé
Couleur :
 
Stock : 0
Notation :
Prix : 22 €
Commentaire(s) : 0 Commentaire(s)

Encore plus concentré et plus exubérant que son petit frère (Sève d'Automne), ce vin est à réserver aux amateurs de grand vins blancs, qui recherchent une complexité aromatique et une singularité dans un vin.

Publié par : truffo, le 22 Février 2010 11:41 pm

Syntaxe Solr

Il est parfaitement possible possible d'utiliser le NOT directement sans passer par un hack. Il suffit d'utiliser la syntaxe classiques des moteurs d'indexation à savoir

...
'filter', array( 'billet/tags: (NOT ""Wink '),
...

C'est syntaxe à l'avantage de permettre de faire des requêtes qui soit plus proche du langage naturel.

Publié par : gandbox, le 23 Février 2010 07:14 pm

Mélange syntaxe eZ Find / Solr

Effectivement, il est possible de combiner l'interface eZ Find, et la syntaxe Solr.
Mais je ne suis pas trop partisan de ce type de mélange, ca reste utile d'étendre la syntaxe de Solr avec l'ensemble des opérateurs utiles (dont le NOT), et d'ailleurs une expression générique du 'empty' multi-datatype serait également un apport utile.