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.
Enjoy!
More background information about this extension on Netgen Blog.
eZ Upgrade has been extended, supporting upgrades of eZ installations as old as 3.8.6, and upgrading them up to 4.3.0.
Now there's no excuse for not moving your 3.x site over to that shiny, new PHP 5 server. :)
Yahoo! Search recently changed their front page to include three of "Earth's Biggest Puzzles". As a long time user I find this really obnoxious especially because there doesn't seem to be any way to turn this off. So I decided to do something about it and I wrote a Greasemonkey script to get rid of it again. You can find the script here.
The Open Source CMS market is complex, with hundreds of projects readily available. Some are written in clean code, others turn out as horrible collections of dirty hacks. Some have sprung out of the anonymous dark, others are maintained by professional teams with release roadmaps, contribution reviews and certifications, and get supported by development guidelines, professional integration and maintenance services. Some of them have huge feature lists. Others keep their kernels small and establish an ecosystem for plugin manufacturers. The third group only accepts generic functionality in the core, so that the majority of practical needs can be met by editing data classes, templates and permissions, which renders plugins meaningless.
In 2003, YMC has chosen eZ Publish as our primary CMS. Over the years, we managed nearly a hundred projects of all sizes, and on the way, trained dozens of developers. With all the experience, we still deem eZ Publish as the most versatile Open Source Content Management Framework in existence. It has allowed for a smooth upgrade path, as it is strictly generalistic in design and both upwards and backwards compatible. Its thourough object orientation might be hard for the beginner, however, the advantages cannot be turned down when it comes to more complex multi-client installations that will be migrated to new versions of the CMS and even PHP. The professional vendor behind eZ Publish (eZ Systems), and the industry-grade services available directly from them (namely eZ Premium and developer certifications), are indespensable for a professional software investment.
In our work as consultants and programmers, we have specialized in two ways. First, we serve large media companies to meet their high-end demands, such as complex migration scenarios, flexible editorial workflows, quick release cycles, seamless scalability and uninterrupted business during migrations. Secondly, YMC has developed an appetite for the new and the fancy, especially in the media sector. We are strong advocats for user generated content, and we can help to create value from it, the more so as we have invested our expertise in several Web 2.0 startups.
Today, YMC initiates a third line of action. We intend to give back to the Open Source community. Therefore, we will publish selected modules under the GPL. All of them have been in stable use for years and undergone several evolutionary iterations. We hope that they will prove useful for other Open Source enthusiasts and help to further promote Open Source at the Enterprise level. Of course, we appreciate any feedback and any suggestions you might have.
We will use Google Code. Here is a list of recent and planned publications. Descriptions for the other numbers will be added shortly.
1) ymcExtensionLoader
Adds enterprise-grade multi-client capability to eZ Publish. Enables a more flexible handling of extensions and settings, sharing settings between clients, and nesting extensions.
2) ymcBootstrap
Introduces an alternative way to control patches to eZ Publish. Changes to the eZ kernel and the database are logged and can be automatically deployed onto a multi-server environment in a reliable manner. This will aid upwards compatibility to further versions of eZ Publish.
3) ymcLibrary
4) ymcClusterManagement
5) ymcDistributedCache
6) ymcMetaNavigation
7) ymcDistributedStorage
8) ymcCommunity
Installing Xdebug seems to be a problem for some users. The main trouble is for Windows users that don't know which file to download. Over the past few days I've worked on a wizard that analyses phpinfo()'s output and for Windows users suggests:
which file to download
where to put the file
which php.ini file to modify, and how
For Unix users, it explains:
which source tarball to download
how to compile
which php.ini file to modify, and how
I hope this makes it a bit easier to get going with Xdebug. Next up (hopefully this week) is release candidate 2 for Xdebug 2.1.0.
NovenINIUpdate 3.0 has just been released.
Many new and useful features such as :
This release also comes with a few bugfixes.
You may check the full changelog.
Go download and upgrade ;-) !
Version 0.9.2 of the PDF catalogue has just been released. This release comes with a new feature that allows one to add any content node to a common PDF catalogue from which users can create a personal PDF catalogue.
A demonstration of the PDF catalogue is available here: http://www.alexander-block.net/eng/Business/eZ-Systems/Personal-PDF-Catalogue (it does currently not support the common PDF catalogue feature)