J'ai publié une "mini" contribution sur la gestion des relations d'objet(s) dans eZ Find. Cette contribution est relativement confidentielle (exploitation marginale), mais constitue une bonne occasion pour présenter le fonctionnement d'eZ Find et sa relation avec les datatypes. eZ Find est une extension encore sous exploitée, alors qu'elle constitue une avancée majeure d'eZ Publish sur la cible "système d'information professionnel", au côté des extensions EZSI ou encore CMIS.
Voir la page du projet ezfsolrdocumentfieldobjectrelation
eZ Find en quelques mots "faciles à comprendre"
- eZ Find est une "interface" entre eZ Publish (le CMS) et Solr (le moteur de recherche)
- Solr est un moteur de recherche autonome, qui s'exécute comme un service JAVA, et qui fonctionne en mode REST, à savoir :
- Lors d'une publication, eZ Find prépare le contenu dans une URL et le "pousse" vers Solr (HTTP)
- Lors d'une recherche (full text, filtres, facettes), eZ Find prépare la question dans une URL et demande à eZ Find la réponse
Toutes ces opérations complexes sont "masqués" pour le développeur, qui doit uniquement se soucier de bien formuler ses requêtes dans son habituel langage de templates : fecth( ezfind, search, params...). La puissance d'eZ Find réside dans cette simplicité d'exploitation, au profit de le puissance fonctionnelle de Solr est des "questions" que l'on peut formuler, notamment sur la pertinence (façon google) ou sur les classification à facettes.
eZ Find est les datatypes
eZ Publish fonctionne sur le concept de "datatype", à savoir des types de données "riches" permettant de représenter des lignes de textes, des numériques, des dates, mais aussi des types de données plus complexes ou exotiques comme des images, des vidéos, des relations de contenus ou des géolocalisations. eZ Publish permet également de définir ses propres datatypes, et on peut donc comprendre que les correspondances entre les types de données eZ Publish et les types de données Solr nécessite quelques paramétrages, selon 2 cas de figures :
- Les correspondances de données parfaitement symétriques : ligne de texte = string
- Les correspondances de données "sur mesure" : relations d'objets (et gestion des sous attributs)
Pour définir ces correspondances eZ Find propose un fichier de paramétrage extension/ezfind/settings/ezfind.ini
Fonctionnement de la classe ezfSolrDocumentFieldObjectRelation
L'aspect "sur mesure" de la correspondance entre les datatypes eZ Publish et les types de données eZ Find implique un point de vue du développeur dans sa façon de gérer les cas particuliers et complexes. L'indexation des relations d'objets multiples est une bonne illustration de l'éternel dilemme du développeur : "jusqu'où faut-il aller ?"
Comportement natif de ezfSolrDocumentFieldObjectRelation
Tous les objets en relations permettent de générer une unique champs "text" par concaténation de tous les attributs de tous les objets. On obtient ainsi un contenu indexé de type "objet1/attribut1 objet1/attribut2 objet2/attribut1 objet2/attribut2". Cette logique est tout à fait adaptée à la recherche "full text", mais inadaptée à l'exploitation de facette. Pour un objet en relation dont le "name" est "mon objet en relation", on obtient les facettes suivantes sur "myclass/myattribute" :
- "mon" (10 résultats)
- "objet" (3 résultats)
- "en" (30 résultats)
- "relation" (5 résultats)
Comportement de l'évolution ezfSolrDocumentFieldObjectRelation
La gestion des facettes devient possible, en spécifiant un attribut en particulier ou alors en invoquant le "name". La page du projet montre quelques exemples de code basiques. En exploitant l'exemple précédent, on obtient alors l'unique facette suivante :
- "mon objet en relation" (3 résultats)
Gestion des filtres de type string
Un fois les facettes générées, il est nécessaire de construire le lien permettant de filtrer les résultats par "mon objet en relation". eZ Find (ou plutôt Solr) exige logiquement que les chaînes de caractères (string) soient encapsulées par des "doubles côtes".
Cet extrait de code (un peu complexe) montre comment étendre le search.tpl pour générer des filtres pour les chaines de caractères : filtres par "text line", "keywords" ou "relation d'objet(s)"
{foreach $search_extras.facet_fields[$index].nameList as $facetID => $name}
{if $name|trim|count_chars|gt(0)}
<li>
{if $search_extras.facet_fields[$index].field|compare('facet_fields')}
{def $url_link = concat($search_extras.facet_fields[$index].queryLimit[$facetID]|explode(':').0,':"',$name|urlencode,'"')}
{else}
{def $url_link = $search_extras.facet_fields[$index].queryLimit[$facetID]|wash}
{/if}
<a title="{$search_extras.facet_fields[$index].countList[$facetID]} Réponse(s) trouvée(s) dans les '{$name|wash}' // " href={concat( $baseURI, '&facet_field=', $facetField|wash, '&filter[]=', $url_link )|ezurl}>{$name|wash}</a> ({$search_extras.facet_fields[$index].countList[$facetID]})
{undef $url_link}
</li>
{/if}
{/foreach}
A noter : L'opérateur urlencode n'est pas natif et doit etre déclaré dans template.ini.append.php :
- PHPOperatorList[urlencode]=urlencode