Smile Virtual Attributes patch for eZ Find ------------------------------------------ > What is it "Virtual attributes" for eZ Find is a feature that allows the developer to customize the indexing mechanism. As we sometimes face special needs, we would like to be able to customize objects indexing (regarding the way your objects will be added to Solr index) on some points. Solr index is per-content focused and you won't be able to get some results based on some cross sensitive relations they could have without a specific handling. Then come the virtual attributes, which allows the developer to handle search-scope custom relations between contents. Some common use-cases : - Complex indexing based on custom logic * Indexing only titles for object relations to handle specific searches * Indexing the title of object relations' parents * Get search results according to children's content * ... and others - Complicated custom facets * Thematic facets in a dedicated attribute, that can also be computed from external values (ranges, ..) * Creating facet by topic based on a complete string (not as separated words) - Custom sorting logics within a dedicated attribute For that kind of needs, a common workaround was to add a dedicated datatype and define an attribute to your eZ Publish class scheme (whose only aim was to implement the indexing logic). With virtual attribute, you will follow the same logic but won't need to create an extra datatype and oversize your database with non sensitive data. The scope of your added attribute will be limited to search, giving you more control on the results to give. > How to install Virtual attributes comes as a patch to eZ Find 2.0. Just apply the diff file to eZ Find 2.0 source code, by using 'patch' command : $ cd __your_ez_root__/extension/ezfind $ patch -p0 < virtual_attributes.diff Your eZ Find installation is now ready to host your virtual attributes as soon as they will be defined. See next steps to know how to use it. > How it works To implement a new custom indexing rule, you will need to associate a handler to a class. This can be done in ezfind configuration file (an override of ezfind.ini) The definition will be as simple as : [IndexSettings] CustomClassIndexer[__YOUR_CLASS_IDENTIFIER__]=__YOUR_VIRTUAL_ATTRIBUTE_HANDLER_CLASSNAME__ The handler is then represented by a class which implements dedicated methods. By now, whenever eZ Find will index an object of class "__YOUR_CLASS_IDENTIFIER__", it will check the handler for some virtual attributes to add in search index. > How to write a handler To write a handler you then just need to create a new class, inheriting from class VirtualAttributeHandler. The handler will be in charge of : - Defining the different attributes that will be virtually added to your class (the method virtualDefinition, which will be called by eZ Find). - Implementing the indexing routines for your virtual attributes. The entry point is then the method "virtualDefinition". As can be the method "definition" for eZPersistentObject, you will have to define an array, defining the virtual attribute identifiers and some properties/options that will allow eZ Find to complete the indexing. The entries will look like : static public function virtualDefinition() { return array( '__VIRTUAL_ATTRIBUTE_IDENTIFIER__' => array( // Required parameters 'type' => '__ATTRIBUTE_TYPE__', // Solr attribute type, ie text|sint|boolean|sfloat|string|sfloat|date // Parameters to be used with with standard metaData 'handler_class' => '__HANDLER_INDEXING_CLASS__', // The class that define the indexation method for this attribute 'handler_method' => '__HANDLER_INDEXING_METHOD__', // The method that implements the indexing routine for this attribute // Optional parameters 'handler_extra_parameters' => array( array( '__AN_EXTRA_PARAMETER_NAME__' => __AN_EXTRA_PARAMETER_VALUE__ ) ), // Parameters that can be passed to the indexing method, this will allow you to write common and more generic indexing methods to be reused. 'boost' => '__ATTRIBUTE_BOOST__', // A boost value for this attribute, according to eZ Find feature 'unsearchable' => true // Whether the attribute value will be searchable or not. Setting it to true will allow you to consider some "facet only" attributes, that won't be searched (won't interfere with standard search results) and will be dedicated to facet queries. } } The definition done, you now have to implement the indexing methods. These should be static and have to comply with the following signature : static function __YOUR_INDEXING_METHOD__( eZContentObject $object, $languageCode, $extraParameters ) { // Your implementation return '__SOME_METADATA__'; } This will have to behave as a standard datatatype "metadata" method, a "string" value is then expected to be returned as the value to be indexed. The implementation donc, you'll be ready to play with your virtual attributes. You may reindex your content and see the results. Depending on how generically the handler has been written, a handler might also be shared between classes. > How to use virtual attributes in fetch queries The defined virtual attributes will simply be available for your queries as they would be if your attributes were real ones. {def $results=fetch( 'ezfind', 'search', hash( query, 'my virtual search', .... ) ) } Searches and facets are then done as usual, the operator syntax remains the same. And here it is, you're then able to define some kind of custom attributes, which will only be known by eZ find and will be available for your queries as if they were real. You can now reach more of your dreamed needs! > Limits - Modifying an object linked by virtual attribute's handler may not update this virtual attribute indexed content. Like in the case of "indexing the Title of object relations' parents", publishing the relation parent won't automatically ask for the virtual attribute reindexing. You will then have to apply specific rules (ie in a content edit handler). > Credits Dominique DE VASCONCELLOS && Alexandre NION Smile ( http://www.smile.fr )