Jean-Luc NGUYEN : Nouvelle extension eZ Publish : PM Compress
Nouvelle contribution : http://projects.ez.no/pm_compress
Publié par Jean-Luc NGUYEN le 23/07/2010 14:59
Nouvelle contribution : http://projects.ez.no/pm_compress
Publié par Jean-Luc NGUYEN le 23/07/2010 14:59
Lorsqu’on a un bug sur eZ Publish, de quelconque nature, j’ai noté au fur et à mesure les raisons possibles et les outils pouvant aider un développeur à le corriger (en mode développement bien sûr).
Publié par Jean-Luc NGUYEN le 07/07/2010 08:45
Voici comme promis mes slides ainsi que le topic sur le forum de Share pour continuer à en discuter
Publié par Jérôme Vieilledent le 28/06/2010 07:57
On June 24th, at the 2010 eZ Conference developer track, I proposed a talk about eZ Find 2.2 customization & advanced development. This talk illustrate and summarize my eZ Find articles / tutorials you'll find below, with new schemas and real project exemples. Thanks to all the eZ Community for their interest and questions during the conference. I hope to have time to write one of these requested tutorials in coming month.
I'd like to thanks Nicolas Pastorino for the english translation of my articles on share.ez.no.
Download the PDF version, or browse the slideshare version.
French articles about eZ Find on gandbox.fr :
English articles about eZ Find (translation from French), on share.ez.no :
Publié par Gilles Guirand le 27/06/2010 17:34
Le gagnant du concours de re-design du site http://share.ez.no est connu. Toutes les infos ici :
http://share.ez.no/blogs/share.ez.no-team/ez-design-contest-and-the-winner-is
Il ne « reste » plus qu’à l’implémenter.
Publié par Jean-Luc NGUYEN le 25/06/2010 10:51
Toutes les infos du direct sur la eZ Conference : http://share.ez.no/live
Publié par Jean-Luc NGUYEN le 22/06/2010 23:24
En voulant corriger un bug sur la prévisualisation des contenus en back-office, j’ai également appris une chose sur la configuration des siteaccess : il est nécessaire de les placer en dehors de l’extension, dans /settings/.
J’ai toujours pensé que c’était une question de « best practice », mais si le répertoire siteaccess se trouve dans /extension/mon_extension/settings/, la prévisualisation ne fonctionne pas.
Il y a d’ailleurs un bug datant de 2006, patché récemment : http://issues.ez.no/IssueView.php?Id=9903
Ce patch ne fonctionne qu’à moitié, on va bien chercher le siteaccess du front-office pour la prévisualisation, mais l’affichage ne prend en compte que le template générique full.tpl, sans passer par les règles du fichier override.ini.append.php.
A savoir donc.
Publié par Jean-Luc NGUYEN le 14/06/2010 12:26
Le billet précédent décrit comment ajouter des champs supplémentaires dans Solr, afin de pouvoir les exploiter avec la syntaxe native d'eZ Find sous la forme 'mycontentclass/mycontentattribute/mycontentsubattribute'.
Cette syntaxe spécifique à eZ Find est certes confortable mais non exclusive, à savoir qu'il est possible de mixer des éléments de syntaxes eZ Find et des éléments de syntaxes Solr, comme par exemple les noms des champs ('attr_myfield_type') ou encore des opérateurs logiques (AND, NOT, etc.).
“- OUI c'est une mauvaise pratique. Une syntaxe 'interface' n'est pas faites pour être outrepasser, au risque de compromettre l'évolutivité de la couche basse, à savoir Solr
”
- OUI cela peut faciliter les développements, voir même sauver la vie du développeur sur certaines situations complexes
Ce billet montre quelques exemples d'exploitation de la syntaxe Solr, volontairement simplifiés pour en faciliter la compréhension.
Il s'agit d'un grand classique des problématiques d'eZ Publish, à savoir :
Résultat : Impossible de mélanger les "Post" et "Article" en les triant par dates décroissante (sauf à développer un terrifiant opérateur de template). Généralement, les développeurs font en sorte d'utiliser une seule classe plus générique afin de contourner ou plutôt déplacer le problème (la mutualisation d'une classe peut avoir d'autres inconvénients).
La solution des attributs communs entre les classes avec eZ Find :
Le premier billet de cette série consacré à eZ Find décrit la logique de nommage des champs dans Solr. Une effet secondaire positif de cette convention (lié au concept de dynamicfields de Solr) est l'absence bienheureuse de l'identifiant de la classe dans le nom de chaque champs. Il est ainsi possible d'exploiter les champs homonymes comme bon nous semble, au travers de recherche, filtres ou tris en fonction du besoin.
Exemple de code de template eZ Publish sur la seule classe "Post" :
{def $search_result = fetch( 'content', 'list', hash( 'parent_node_id', 2, 'class_filter_type', 'include', 'class_filter_array', array(24), 'sort_by', array( array( 'attribute', false(), 'post/date' ) ), 'limit', 10, 'depth', 3 ))}
Exemple équivalent de code de template eZ Find pour notre problématique de tri inter-classes "Post" et "Article" :
{def $search=fetch( ezfind, search, hash( query , '', 'class_id', array('post', 'article'), 'limit', 10, 'sort_by', hash('attr_date_dt', 'desc') ))}
A noter : une évolution souhaitable d'eZ Find serait de pouvoir exploiter une syntaxe du type '//date', afin de rendre facultatif l'ajout de la classe dans le filtre Solr généré.
Contrairement à l'exemple précédent sur les dates, les keywords disposent dans eZ Publish d'une table externe au contenu (ezkeyword_attribute_link), permettant de lier chaque keyword à divers contenus de diverses classes. Cependant le fetch par keyword ne dispose pas de tous les filtres possibles d'un fetch par list par exemple (class_filter_type, class_filter_array, extended_attribute_filter, etc.). Cette limitation se comprend puisque permettre un filtre inter-classes engendre forcement une limitation sur les fonctionnalités liées aux attributs spécifiques à chaque classes.
Sur le même logique que le traitement par date, on peut donc exploiter eZ Find pour effectuer toutes les opérations nécessaires autour des keywords. Voici un exemple de code :
'filter', array('attr_tags_lk:"ez publish"', 'NOT attr_title_t:"RSS"')
Résultat : Retourne uniquement les résultats associés au keyword "eZ Publish" ou "ez publish" (notez l'utilisation du _lk pour lowercase), ne contenant pas "RSS" dans le titre
'filter', array('attr_tags_lk:"ez publish"', 'attr_tags_lk:"mootools"')
Résultat : Retourne uniquement les résultats associés à la fois au keyword "eZ Publish" ou "ez publish", et au keyword "Mootools" ou "mootools"
Voici quelques exemples de filtres, qui n'ont rien d'exhaustif puisqu'il est possible d'exploiter l'ensemble des opérateurs Lucene en fonction de la version de Solr déployée (version de Solr 1.4, disponible dans eZ Find 2.2 lors de la rédaction de ce billet).
'filter', array('NOT ( attr_title_t:(ez+find) OR attr_intro_t:(ez+find) )')
Résultat : Retourne uniquement les résultats qui possèdent l'expression 'ez find' ou 'eZ Find', dans l'attribut 'title' ou l'attribut 'Intro'. Il faut noter l'utilisation de la version 'text' (_t) sur l'attribut 'title' permettant de profiter du non respect de la casse (contrairement au type 'string').
'filter', array('attr_title_s:[A TO G] AND ezf_df_text:google~0.7')
Résultat : Retourne uniquement les résultats dont le 'title' commence par A,B,C,D, E ou F (G exclu), et dont le contenu possède approximativement l'expression 'google' (Google, iGoogle, etc.).
Publié par Gilles Guirand le 23/05/2010 19:17
Le billet précédent décrit les mécanismes bas niveaux d'eZ Find, et la façon dont les correspondances entre les attributs eZ Publish (noms, types de champs) et les champs Solr sont gérés. Ce billet décrit comment eZ Find peut considérablement faciliter le développement de certaines fonctionnalités (en évitant de complexes opérateurs de templates aux multiples requêtes SQL...), en ajoutant automatiquement des champs dans Solr lors de l'indexation d'un contenu, ré-exploitables par la suite pour la construction d'une facette par exemple ou pour profiter d'un filtre supplémentaire.
L'exemple étudié a surtout une valeur pédagogique, puisqu'il s'agit d'un besoin générique et relativement simple à implémenter. Les listes d'actualités, ou les listes de billets sur les Blogs proposent généralement des filtres par années (2010) ou par mois / année (Janvier 2010) (comme sur ce blog par exemple dans la colonne de droite). Habituellement, pour ce genre de filtre on développe un opérateur de template permettant d'effectuer la requête SQL nécessaire, ce qui peut rapidement devenir très complexe. Il suffit de lire le code de l'opérateur de template eZArchive pour en comprendre les limites.
Il est relativement fréquent que ces manipulations SQL souffrent de carences fonctionnelles, comme la propagation des droits, la gestion des langues, la gestion de certaines subtilités entre MySql ou PostGreSql. Ce sont des problématiques à la charge du développeur, puisque l'on contourne les API pour exploiter directement du SQL. Par ailleurs, l'opérateur eZArchive montre une autre limite importante, puisqu'il se contente de travailler sur la date de publication 'publication_date' (par facilité), et ne permet donc pas d'exploiter un attribut de date spécifique à la classe.
Les settings d'eZ Find (ezfind.ini, à surcharger dans le ezfind.ini.append.php de votre extension) permettent de déléguer le traitement de l'indexation d'un datatype eZ Publish vers une classe PHP :
[SolrFieldMapSettings] CustomMap[ezdate]=ezfSolrDocumentFieldDate
Notre classe PHP, nommée arbitrairement ezfSolrDocumentFieldDate hérite de la classe ezfSolrDocumentFieldBase et doit être ajoutée dans le dossier /extension/myextension/classes/ezfsolrdocumentfielddate.php avec le squelette suivante :
<?php class ezfSolrDocumentFieldDate extends ezfSolrDocumentFieldBase { public static function getFieldName( eZContentClassAttribute $classAttribute, $subAttribute = null, $context = 'search' ) { // return the fieldname like : attr_mydate_d } public function getData() { // return the array keys (fieldname => value), like : array('attr_mydate_dt' => '2010-04-30T00:00:00Z') } } ?>
Cette méthode est invoquée pour transformer les noms des attributs eZ Find vers les noms de champs Solr. Ainsi lorsqu'on construit une facette avec la syntaxe 'mycontentclass/mydateattribute', cette méthode reçoit 'mydateattribute' et doit retourner 'attr_mydateattribute_dt'. Nous allons donc implémenter cette fonction de la façon suivante :
const DEFAULT_SUBATTRIBUTE_TYPE = 'date'; public static function getFieldName( eZContentClassAttribute $classAttribute, $subAttribute = null, $context = 'search' ) { switch ( $classAttribute->attribute( 'data_type_string' ) ) { case 'ezdate' : { if ( $subAttribute and $subAttribute !== '' ) { // A subattribute was passed return parent::generateSubattributeFieldName( $classAttribute, $subAttribute, self::DEFAULT_SUBATTRIBUTE_TYPE ); } else { // return the default field name here. return parent::generateAttributeFieldName( $classAttribute, self::getClassAttributeType( $classAttribute, null, $context ) ); } } break; default: {} break; } }
Cette méthode est invoquée pour extraire les données d'eZ Publish, et les préparer pour leur indexation vers Solr. C'est donc dans cette méthode que l'on peut ajouter nos champs supplémentaires 'year' et 'yearmonth'. Pour faciliter la future exploitation de ces champs avec eZ Find, je souhaite pouvoir construire des facettes ou des filtres selon la syntaxe classique :
public function getData() { $contentClassAttribute = $this->ContentObjectAttribute->attribute( 'contentclass_attribute' ); switch ( $contentClassAttribute->attribute( 'data_type_string' ) ) { case 'ezdate' : { $returnArray = array(); // Get timestamp attribute value $value = $this->ContentObjectAttribute->metaData(); // Generate the main filedName attr_XXX_dt $fieldName = parent::generateAttributeFieldName( $contentClassAttribute, self::DEFAULT_ATTRIBUTE_TYPE ); $returnArray[$fieldName] = parent::convertTimestampToDate( $value ); // Generate the yearmonth subattribute filedName subattr_year_dt $fieldName = parent::generateSubattributeFieldName( $contentClassAttribute, 'year', self::DEFAULT_SUBATTRIBUTE_TYPE ); $year = date("Y", $value); // Get Year value : 2010 $returnArray[$fieldName] = parent::convertTimestampToDate( strtotime($year.'-01-01') ); // Generate the yearmonth subattribute filedName subattr_yearmonth_dt $fieldName = parent::generateSubattributeFieldName( $contentClassAttribute, 'yearmonth', self::DEFAULT_SUBATTRIBUTE_TYPE ); $month = date("n", $value); // Get Month value : 3 $returnArray[$fieldName] = parent::convertTimestampToDate( strtotime($year.'-'.$month.'-01') ); return $returnArray; } break; default: {} break; } } }
A noter : $returnArray contient un tableau à clés, dont voici un exemple de sortie (effectuer avec var_dump) :
array(3) { ["attr_date_dt"]=> string(24) "2008-12-28T00:00:00.000Z" ["subattr_date-year_dt"]=> string(24) "2008-01-01T00:00:00.000Z" ["subattr_date-yearmonth_dt"]=> string(24) "2008-12-01T00:00:00.000Z" }
A noter : Solr utilise le format de date ISO 8601, du type '2010-04-30T00:00:00Z'. La classe parent ezfSolrDocumentFieldBase propose la méthode convertTimestampToDate() pour convertir un format timestamp vers un format ISO 8601.
Nos données par années et par mois-année sont maintenant disponibles. Il ne reste plus qu'à construire nos facettes avec la syntaxe habituelle :
{def $search_yearmonth=fetch( ezfind, search, hash( query , '', 'facet', array( hash('field', 'billet/date/year', 'sort', 'alpha', 'limit', 20 ), hash('field', 'billet/date/yearmonth', 'sort', 'alpha', 'limit', 20 ) ), 'class_id', array('billet'), 'subtree_array', array(2) ))} {def $search_extras_year=$search_yearmonth['SearchExtras'].facet_fields[0].nameList|reverse} {def $search_extras_yearmonth=$search_yearmonth['SearchExtras'].facet_fields[1].nameList|reverse} {def $date_count = 0 $date_ts = 0} <li id="blog_block_10" class="colonne_block"> <h1>Archives par années :</h1> <ul class="{$current_css} list"> {foreach $search_extras_year as $facetID => $datevalue} {set $date_count = $search_yearmonth['SearchExtras'].facet_fields[0].countList[$facetID]} {set $date_ts = $datevalue|strtotime} <li><a href={concat('/Blogs/(year)/',$date_ts|datetime( 'custom', '%Y' ))|ezurl} title="Archives : {$date_ts|datetime( 'custom', '%Y' )} // {$date_count} Billet(s)">{$date_ts|datetime( 'custom', '%Y' )}</a></li> {/foreach} </ul> </li> <li id="blog_block_11" class="colonne_block"> <h1>Archives par mois / années :</h1> <ul class="{$current_css} list"> {foreach $search_extras_yearmonth as $facetID => $datevalue} {set $date_count = $search_yearmonth['SearchExtras'].facet_fields[1].countList[$facetID]} {set $date_ts = $datevalue|strtotime} <li><a href={concat('/Blogs/(year)/',$date_ts|datetime( 'custom', '%Y' ),'/(month)/',$date_ts|datetime( 'custom', '%n' ))|ezurl} title="Archives : {$date_ts|datetime( 'custom', '%F %Y' )} // {$date_count} Billet(s)">{$date_ts|datetime( 'custom', '%F %Y' )|upfirst}</a></li> {/foreach} </ul> </li> {undef $date_ts $date_count $search_yearmonth $search_extras_yearmonth}
A noter : Le fetch proposé est relativement basique, afin de faciliter la compréhension du mécanisme. Il faut bien sur faire évoluer le code pour obtenir le fonctionnel attendu (utiliser les filtres par exemple), mais ce n'est pas l'objet de ce billet puisque la documentation officielle détaille déjà la façon de procéder.
A noter : le 'sort', 'alpha' ne permet pas réellement de spécifier que l'on souhaite un tri alphabétique. Il s'agit surtout de spécifier que l'on ne souhaite pas un tri par 'count' (nombre d'items associés à la facette). Dans ce cas Solr applique un tri automatique 'croissant' en fonction de son index et du type de donnée (ce qui explique l'utilisation de l'opérateur reverse pour obtenir une liste décroissante).
Publié par Gilles Guirand le 16/05/2010 15:30
Après 2 billets un peu "rapides" sur eZ Find et la gestion des datatypes, ainsi que l'utilisation des facettes pour construire un nuage de tags, voici le premier billet d'une série de tutoriels à propos d'eZ Find, qui décrivent plus en détail son fonctionnement et son utilisation avancée dans divers contextes. Cette série de tutoriels introduit quelques nouveautés de la version 2.2, sera traduite progressivement sur le share.ez.no, et servira de base pour une conférence de la eZ Conference 2010, ainsi qu'aux Recontres Mondiales du Logiciel Libre 2010
Cet article décrit comment eZ Find transforme et adapte les contenus eZ Publish, et leurs datatypes respectifs pour les indexer dans Solr. La compréhension de ces mécanismes bas niveaux d'eZ Find sont des prérequis indispensables lors des phases de développement et de debug, ne serait ce que pour savoir ou chercher et lire les portions de codes permettant de comprendre le rôle exact d'un settings, d'un paramètre ou d'un filtre.
Cet article n'a pas vocation à expliquer à nouveau comment installer et indexer son contenu avec eZ Find. La documentation décrit avec précision les opérations à effectuer. Cependant voici quelques astuces permettant de développer dans de bonnes conditions :
Il est parfois laborieux de relancer une indexation complète juste pour tester l'impact d'une modification mineure. Alors il existe pour cela quelques paramètres cachés dans le script /bin/php/updatesearchindexsolr.php, qui permettent de désigner un noeud parent de départ, ainsi q'une limite (attention les 3 paramètres combinés sont nécessaires) :
php extension/ezfind/bin/php/updatesearchindexsolr.php --siteaccess=monsiteaccess --topNodeID=2546 --offset=0 --limit=10
Pour savoir si vos contenus et vos attributs sont correctement indexés, il suffit d'effectuer une recherche dans l'interface Web d'administration de Solr : http://localhost:8983/solr/admin/. Cette interface est également utile pour vérifier comment les champs Solr ont été nommés, par exemple sur la version d'eZ Find 2.2, on peut observer 2 champs qui semblent des doublons concernent les titres des articles : attr_title_s et attr_title_t. La suite du billet détaille le comment et le pourquoi de ce comportement.
En laissant une console active, pour pourrez observer les messages envoyés vers Solr de la forme :
INFO: [] webapp=/solr path=/select params={ ... MESSAGE ... } status=400 QTime=5
Ce message peut être copier / coller à partir de la console, vers la fin de l'URL dans l'interfaçe d'administration de Solr : http://localhost:8983/solr/select/?MESSAGE. On obtient ainsi une sortie exacte de ce que Solr envois à eZ Find avant transformation. Cette manipulation est utile lors des phases de Debug, par exemple en manipulant directement le message pour obtenir exactement le résultat attendu.
Voici le parcours d'exécution du code lors de l'ajout / modification d'un contenu eZ Publish :
eZ Find est construit comme un plug-in de recherche, c'est à dire que le module /content/search a été nativement construit pour être déporté sous forme de plug-in. Ainsi dans l'extension /ezfind/settings/site.ini.append.php on trouve la déclaration du plug-in :
[SearchSettings] SearchEngine=ezsolr
C'est ensuite la méthode getEngine() (kernel/classes/ezsearch.php) qui s'occupe d'affecter la bonne classe PHP pour interfacer le plug-in de recherche, à savoir : /search/plugins/ezsolr/ezsolr.php
Lors des différentes opérations de mises à jours de contenus, la méthode addObject de la classe eZSolr sera invoqué. Ce mode de fonctionnement en plug-in permet également d'hériter des autres mécanismes natifs de la recherche eZ Publish, comme par exemple le DelayedIndexing, qui permet de déporter l'indexation (complète ou par classes) vers une tache planifiée : indexcontent.php :
[SearchSettings] DelayedIndexing=disabled|enabled|classbased DelayedIndexingClassList[] DelayedIndexingClassList[]=mycontentclass
A noter : Cette technique est relativement efficace pour optimiser les temps de réponses Back Office, ou les imports de contenus régulier. Cependant, le DelayedIndexing souffre de quelques limites, puisqu'il est générique (et non optimisé spécifiquement pour eZ Find) et qu'il se contente donc de boucler sur la table 'ezpending_actions' afin d'indexer les objets un par un sans se préoccuper des autres finesses de Solr, comme par exemple l'ajout massif de contenus à indexer, suivi d'un unique 'commit'.
La méthode addObject (/search/plugins/ezsolr/ezsolr.php) reçoit :
Cette méthode agit de la façon suivante, dans les grandes lignes :
A noter : Depuis eZ Find 2.2, il est possible d'utiliser des 'cores' spécifiques à chaque langues (/extension/ezfind/java/solr.multicore), ce qui permet de dédier des index et des fichiers de configurations spécifiques à chaque langue (spellings.txt, synonmys.txt, stopwords.txt, etc.)
Il est nécessaire de revenir sur la façon dont eZ Find nomme les champs transmis à Solr. Les principales techniques d'exploitations avancées d'eZ Find pour eZ Publish nécessitent de bien comprendre la sémantique et le mécanisme de nommage des champs.
C'est la classe /ezfind/classes/ezfsolrdocumentfieldbase.php, ou d'éventuelles classes héritées pour certains datatypes complexes (voir ma contribution ezfsolrdocumentfieldobjectrelation par exemple) qui a vocation à créer les noms des champs pour Solr, en respectant une sémantique très précise. On obtient ainsi la sémantique suivante :
Le nom des attributs :
Le nom des métadonnées :
Le nom des sous-attributs (inexploité par défaut) :
Nativement, les sous attributs sont peu ou pas exploités. C'est par contre un formidable outil pour étendre le fonctionnement d'eZ Find et indexer des champs supplémentaire. Voir par exemple ma contribution : ezfsolrdocumentfieldobjectrelation, qui indexe tous les attributs des objets en relations, en les stockant dans des sous attributs, ce qui permet ensuite d'effectuer toutes les opérations nécessaires sur ces sous attributs (recherche, filtre, facettes), selon la syntaxe 'myclass/myattribute/mysubattribute'. Les prochains billets détailleront comment exploiter ce mécanisme pour bien d'autres usages.
Dans les noms de champs Solr, la dernière information désigne le type de champs, et donc comment Solr va devoir considérer l'information (entre un string, un texte, une date, un tableau, etc.)
Coté eZ Find, cette définition se fait comme toujours dans les settings. Depuis eZ Find 2.2, il est maintenant possible de définir un type de champs spécifique à chaque contexte d'utilisation :
Par exemple, par défaut, dans la version actuelle d'eZ Find 2.2, les attributs de type 'textline' sont définis différemment pour les tris :
L'impact au niveau de Solr, c'est que tous les attributs de type 'textline' auront systématiquement 2 champs de correspondance :
A noter : il est conseillé d'utiliser également le type 'string' pour les facettes, afin de considérer le caractère espace comme un caractère lambda, et ainsi obtenir des facettes de type 'ma facette', plutôt que 'ma' et 'facette'.
Solr possède un fichier de configuration permettant à eZ Find de lui spécifier que le '_s' signifie un string, le '_t' un texte, etc. Il s'agit du fichier /ezfind/java/solr/conf/schema.xml
Ce fichier de configuration contient la définition d'un certain nombre de noms de champs en dur (pour les meta-données par exemple), mais définie également les correspondances pour tous les noms de champs dynamiques (nos fameux attributs de classes eZ Publish) :
<dynamicField name="*_i" type="int" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_f" type="float" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_d" type="double" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_si" type="sint" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_sf" type="sfloat" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_sd" type="sdouble" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_s" type="string" indexed="true" stored="true" multiValued="true" termVectors="true"/> <dynamicField name="*_sl" type="slong" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_l" type="long" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_t" type="text" indexed="true" stored="true" multiValued="true" termVectors="true"/> <dynamicField name="*_b" type="boolean" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_dt" type="date" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_random" type="random" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_k" type="keyword" indexed="true" stored="true" multiValued="true"/> <dynamicField name="*_lk" type="lckeyword" indexed="true" stored="true" multiValued="true"/> <!-- some trie-coded dynamic fields for faster range queries --> <dynamicField name="*_ti" type="tint" indexed="true" stored="true"/> <dynamicField name="*_tl" type="tlong" indexed="true" stored="true"/> <dynamicField name="*_tf" type="tfloat" indexed="true" stored="true"/> <dynamicField name="*_td" type="tdouble" indexed="true" stored="true"/> <dynamicField name="*_tdt" type="tdate" indexed="true" stored="true"/> <!-- geopoint for geospatial/location searches, boosting, ... --> <dynamicField name="*_gpt" type="geopoint" indexed="true" stored="true"/>
Ce fichier permet aussi de définir des comportements plus complexes sur certains datatypes eZ Publish, comme par exemple les mots clés (keyword). On y trouve par exemple 2 types de champs différents pour la gestion des keywords ('keyword' pour un respect de la casse et 'lckeyword' pour une casse en lowercase), qui peuvent etre exploité indifféremment au niveau d'eZ Find (DatatypeMap).
<fieldtype name="lckeyword" 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>
La définition des keywords est riche d'enseignement sur la configuration de Solr. On peut observer le fonctionnement des appels des filtres Solr, et comment sont traités les séparations de mots par des virgules (PatternTokenizerFactory), la gestion de la casse (LowerCaseFilterFactory), ou encore la suppression des doublons (RemoveDuplicatesTokenFilterFactory), etc.
Publié par Gilles Guirand le 09/05/2010 15:07