A feedable is an object which is generated from the data of a content bean and which the CAE Feeder sends to the Search Engine for indexing. Customizing feedables means that you define which content of a content bean is mapped to fields of the feedable and is therefore added to the index if a corresponding Solr index field exists. The following paragraphs describe the involved classes.
The FeedableContentBeanEvaluator
creates feedables from
ContentBean
objects. You can find the configuration in the
file caefeeder-triggers.xml
, which is located in the classpath
/framework/spring/caefeeder
.
<bean name="contentEvaluator" class= "com.coremedia.amaro.cae.feeder.FeedableContentBeanEvaluator"> <property name="contentBeanFactory" ref="contentBeanFactory"/> <property name="keyTransformer" ref="feederKeyTransformer"/> <property name="feedableFactory" ref="feedableFactory"/> <property name="feedablePopulator" ref="errorHandlingFeedablePopulator"/> </bean>
Example 5.5. Definition of FeedableContentBeanEvaluator
An implementation of com.coremedia.cap.feeder.persistentcache.KeyTransformer is used to create identifiers for Search Engine documents in the index. The default KeyTransformer implementation creates identifiers of the same format as the IdProvider of the CoreMedia CAE.
Example: a content bean for the content with the numerical id 42
is
represented by an Apache Solr document with the value
contentbean:42
in the field id
. Search applications can use the
IdProvider
to get a content bean for the identifier again.
The FeedableContentBeanEvaluator
uses an implementation of
com.coremedia.cap.feeder.populate.FeedablePopulator
to fill the elements of the feedable with the values of a content bean. By default, a
BeanMappingFeedablePopulator
is used which maps Java bean properties of
ContentBean
objects to elements of the created feedable as configured.
If required, you can configure additional FeedablePopulator
implementations in the property populators
of the bean
compositeFeedablePopulator
. The property takes a list of
FeedablePopulator<T>
beans, which makes it possible to combine data from different
implementations into the same feedable. The type parameter <T>
of a configured
FeedablePopulator
bean must be ContentBean
, Content
or a super type
of these. You can find some existing FeedablePopulator
implementations in package
com.coremedia.cap.feeder.populate. For example, you may configure
an additional PropertyPathFeedablePopulator to index certain nested values of struct properties.
If a bean property's get method throws an exception, the CAE
Feeder will index a so-called error document in the index as placeholder. Error
documents can be recognized by the value ERROR
in the index field
feederstate
. The stack trace of the exception is stored in the index field
feederinfo
. Do not forget to always add a feederstate:SUCCESS
clause to your queries to find successfully indexed documents. Bean feeding will by default
automatically be retried after 10 minutes or if a dependency is invalidated that was
accessed before the exception was thrown. Errors are handled by an instance of class
com.coremedia.cap.feeder.populate.ErrorHandlingFeedablePopulator
which wraps all FeedablePopulator
instances. It is available in the Spring
Context as bean errorHandlingFeedablePopulator
and can be customized as
described in its API documentation.
Defining the Properties for Indexing
The BeanMappingFeedablePopulator class has two properties that you can use for customizing the mapping between content bean properties and Feedable.
beanPropertiesByClass
beanMappings
beanMappings
offers more powerful options. You can, for example, add
a property converter implementation that maps to a specific type.
Using beanPropertiesByClass
This configuration provides a simple way for bean properties which are mapped to feedable elements
with the same name. The values of these bean properties are written to an index field with the same name,
if it exists. Furthermore, the bean property values will always be appended to the textbody
index field.
In more detail, the property beanPropertiesByClass
of the
BeanMappingFeedablePopulator
takes a java.util.Map
object, which maps bean classes to comma-separated
strings of their indexed bean properties. This map is available in the Spring application
context under the name caeFeederBeanPropertiesByClass
and can be customized.
The following example defines the mapping for content beans of classes
com.coremedia.example.contentbeans.Text
and
com.coremedia.example.contentbeans.Download
. For content beans of class
Text
and subclasses, the Java bean properties headline
and
text
map to elements of the feedable. When constructing a feedable the
BeanMappingFeedablePopulator
calls the property methods getHeadline
and getText
of class
Text
to retrieve the values for these elements.
<customize:append id="caeFeederBeanPropertiesByClassCustomizer" bean="caeFeederBeanPropertiesByClass"> <map> <entry key="com.coremedia.example.contentbeans.Text" value="headline,text"/> <entry key="com.coremedia.example.contentbeans.Download" value="data"/> </map> </customize:append>
Using beanMappings
A more powerful configuration is available with the property beanMappings
of the
BeanMappingFeedablePopulator.
The new options are:
Define to which search field a content bean property is mapped
Define that a content bean property should not be mapped to the
textBody
field of SolrDefine your own property converter
Define a default value when a property returns null
Adding parameters to a feedable
The property beanMappings
takes a list of mappings where each mapping applies
to one bean class. You can customize this list of mappings as shown below. A mapping for a single bean class
is represented by a
com.coremedia.cap.feeder.bean.BeanFeedableMapping.
Each
BeanFeedableMapping
contains a list of mappings for Java bean properties of the bean class in the property
beanPropertyMappings
. A mapping for a single Java bean property to an element
of the Feedable is represented
by a
com.coremedia.cap.feeder.bean.BeanPropertyFeedableElementMapping.
See Example 5.6, “Example Content Bean to Feedable Mapping” for an example.
Note | |
---|---|
A content bean can inherit from or extend other content beans. In this case, you might have different
BeanFeedableMapping elements that match for an instance of a content bean. If so, the order
of the |
Example 5.6, “Example Content Bean to Feedable Mapping” defines a mapping for the superclass of all content beans
com.coremedia.objectserver.beans.ContentBean.
The bean property content.modificationDate
maps to the feedable element named
freshness
. The default Solr index schema defines an index field with that name, to which the
bean property's value is written.
The bean property uses the syntax of Spring framework's bean wrapper
for nested properties. When constructing a feedable the
BeanMappingFeedablePopulator
calls the property methods getContent().getModificationDate()
of class
ContentBean
to retrieve the value for the element. Furthermore, the value is not added to the
textbody
index field.
Keep in mind, that if you define a mapping for freshness
for any other content bean class
and add it behind this example mapping to the list of mappings, it would be overwritten by our example definition and
you would get a warning in the log file. So, avoid this.
<customize:append id="caeFeederBeanMappingsCustomizer" bean="caeFeederBeanMappings"> <list> <ref local="exampleBeanFeedableMapping"/> </list> </customize:append> <bean id="exampleBeanFeedableMapping" class="com.coremedia.cap.feeder.bean.BeanFeedableMapping"> <property name="beanClass" value="com.coremedia.objectserver.beans.ContentBean"/> <property name="beanPropertyMappings"> <list> <bean class="com.coremedia.cap.feeder.bean. BeanPropertyFeedableElementMapping"> <property name="beanProperty" value="content.modificationDate"/> <property name="feedableElement" value="freshness"/> <property name="textBody" value="false"/> </bean> </list> </property> </bean>
Example 5.6. Example Content Bean to Feedable Mapping
See the API documentation for a description of all properties of the classes
BeanMappingFeedablePopulator,
BeanFeedableMapping
and
BeanPropertyFeedableElementMapping
in package com.coremedia.cap.feeder.bean
.
Mapping of Property Types
The CAE Feeder supports String, Number, Date, XML and binary element types. The following table describes the default mapping from Java bean property value classes to element types:
property value class | element type |
---|---|
com.coremedia.cap.common.Blob | Binary |
java.util.Date and java.util.Calendar
| Date |
com.coremedia.xml.Markup | XML |
java.lang.Number and primitive number types | Number |
java.lang.String
| String |
java.lang.Collection with elements of above types | depends on collection's element type |
Table 5.2. Feedable Element Types for Java Bean Properties
Values of other classes map to String elements with the value of their toString
method. Collections must contain elements of one type, otherwise the value of the elements'
toString
method will be used.
Collection elements can be used to feed multi-value fields in Apache Solr.
You can configure a property converter to convert the value to one of the supported types. A
property converter implements the interface
com.coremedia.cap.feeder.bean.PropertyConverter
and can be configured with the propertyConverter
property of the
BeanPropertyFeedableElementMapping
. Property converters are for example
useful when indexing collection properties. The property converter
implementations
com.coremedia.cap.feeder.bean.CollectionPropertyConverter and
com.coremedia.cap.feeder.bean.CollectionToStringPropertyConverter
can be used for this purpose. Please see the Javadoc for details.
Furthermore, it is possible to configure a default value which should be indexed if a bean
property is null
or a configured PropertyConverter returns null
. A
default value can be configured with the defaultValue
property of the
BeanPropertyFeedableElementMapping. Again, please see the Javadoc for details.