ContentBean's and Solr schema.xml - BloomReach Experience - Open Source CMS

This article covers a Hippo CMS version 11. There's an updated version available that covers our most recent release.

ContentBean's and Solr schema.xml

Your (Identifiable)ContentBean's and Solr schema.xml are related to each other as follows:

Every public getter with an @IndexField annotation must be accounted for in the Solr schema.xml

Title field with setter and re-populate from search result

Thus, if we have the following code in your bean:

private String title;
@IndexField
public String getTitle() {
    return title == null ? (String)getProperty("example:title"): title ;
}
public void setTitle(String title) {
    this.title = title;
}

then the Solr schema.xml must contain (store="true" is optional but needed if you want to sort on the field or re-populate the field from the search result):

<field name="title" type="text_general" indexed="true" stored="true" />

If you want the HippoQueryResult to have the title populated from the Solr result, make sure you store the field

This way the title field will available without calling HippoQueryResult.setContentBeanBinders()

If you do not need to have the field to be populated from the search result (for example getContent, or a getter for some Compound because Compound cannot be re-populated), use store=false.

Title field without setter

Assume we have the following code in your bean:

@IndexField
public String getTitle() {
    return getProperty("example:title");
}

then the Solr schema.xml must contain:

title does not need to be stored:

<field name="title" type="text_general" indexed="true" stored="false" />

@IndexField with an explicit name

Assume we have the following code in your bean:

Index getNewsTitle as title:

@IndexField(name="title")
public String getNewsTitle() {
    return getProperty("example:newstitle");
}

then, your Solr schema.xml must contain

title does not need to be stored:

<field name="title" type="text_general" indexed="true" stored="false" />

@IndexField on a getter that returns array or Collection

Assume we have the following code in your bean:

@IndexField
public String[] getAuthors() {
     return getProperty("example:authors");
}
@IndexField
public List<String> getAuthorsList() {
     String[] authors = getProperty("example:authors");
     return Arrays.asList(authors);
}

then, your Sorl schema.xml must contain

For arrays or collections we need multiValued=true:

<field name="authors" type="text_general" indexed="true" stored="false"
       multiValued="true"/>
<field name="authorsList" type="text_general" indexed="true" stored="false"
       multiValued="true"/>

@IndexField on a getter that returns a ContentBean (Compound)

Assume we have the following code in your bean:

@IndexField
public List<Author> getAuthors() {
    return getChildBeans(Author.class);
}

And

Author bean:

@IndexField
public String getFirstName() {
    return getProperty("example:firstname")
}
@IndexField
public String getLastName() {
    return getProperty("example:lastname")
}

Then your Solr schema.xml does NOT need an extra field. This is because any compound field is accounted for already by the dynamic field mappings below:

Compound fields are mapped to dynamic field mappings by default:

<dynamicField name="*_multiple_compound_mi"  type="int"    indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_ms"  type="string"  indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_ml"  type="long"   indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_mt"  type="text_general"
              indexed="true"  stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_mb"  type="boolean" indexed="true"
              stored="false"  multiValued="true"/>
<dynamicField name="*_multiple_compound_mf"  type="float"  indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_md"  type="double" indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_mdt"  type="tdate" indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_i"  type="int"    indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_s"  type="string"  indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_l"  type="long"   indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_t"  type="text_general"
              indexed="true"  stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_b"  type="boolean" indexed="true"
              stored="false"  multiValued="true"/>
<dynamicField name="*_multiple_compound_f"  type="float"  indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_d"  type="double" indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_multiple_compound_dt"  type="tdate" indexed="true"
              stored="false" multiValued="true"/>

<dynamicField name="*_compound_mi"  type="int"    indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_compound_ms"  type="string"  indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_compound_ml"  type="long"   indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_compound_mt"  type="text_general" indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_compound_mb"  type="boolean" indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_compound_mf"  type="float"  indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_compound_md"  type="double" indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_compound_mdt"  type="tdate" indexed="true"
              stored="false" multiValued="true"/>
<dynamicField name="*_compound_i"  type="int"    indexed="true"
              stored="false"/>
<dynamicField name="*_compound_s"  type="string"  indexed="true"
              stored="false"/>
<dynamicField name="*_compound_l"  type="long"   indexed="true"
              stored="false"/>
<dynamicField name="*_compound_t"  type="text_general" indexed="true"
              stored="false"/>
<dynamicField name="*_compound_b"  type="boolean" indexed="true"
              stored="false"/>
<dynamicField name="*_compound_f"  type="float"  indexed="true"
              stored="false"/>
<dynamicField name="*_compound_d"  type="double" indexed="true"
              stored="false"/>
<dynamicField name="*_compound_dt"  type="tdate" indexed="true"
              stored="false"/>
{code]

If you'd like to make a more explicit mapping for the *List<Author>
 getAuthors()* compound getter, you could add:

{code:language=java|linenumbers=true|title=Explicit field for compound}
<field name="authors_firstName_multiple_compound_s"  type="string"
       indexed="true"  stored="false" multiValued="true"/>
<field name="authors_lastName_multiple_compound_s"  type="string"
       indexed="true"  stored="false" multiValued="true"/>

The field name is authors_firstName_multiple_compound_s because

  1. getter is getAuthors -> authors

  2. getter in Comound is getFirstName -> firstName

  3. It is a collection -> multiple

  4. It is a compound -> compound

  5. The return value is String --> s (if return value would be String[] or Collection<String> it would be ms)

For field name logic, also see Compound ContentBean indexing.

Indexing one field multiple times

When you'd like to index a single property twice, you can create two getters with an @IndexField annotation, however, cleaner is to account for it in the Solr schema.xml

For example:

<field name="title" type="text_general" indexed="true" stored="true" />
<field name="title_rev" type="text_general_rev" indexed="true"
       stored="false" />
<copyField source="title" dest="title_rev"/>
<copyField source="title" dest="text"/>

Now, the title field also will be indexed on the title_rev (for efficient prefix wildcard searches if you would want to) field and the text field. Typically, by default, the text field is searched in (when no specific field is indicated in the SolrQuery) because:

<!-- field for the QueryParser to use when an explicit fieldname
     is absent -->
<defaultSearchField>text</defaultSearchField>
Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?