Writing a custom SOLR search for an AppWithinMinutes application

Last modified by Anca Luca on 2021/12/10

This tutorial shows how to write a customized SOLR search screen in XWiki for an AWM application. For this example we have used the "Expense Report" application.

The objective was to build a search screen that would only return expense reports and would display facets using some of the expense report fields. In the example we will be adding facets for the status, organisation, currency, client and user fields of the expense report class.

Also we will build a "List Facet" allowing to display the facet for StaticList as well as DBList fields. This facet code can be reused for any field of this type.

Configuration Code for the SOLR Search

We customize the "filterQuery", "facetFields" and "facetDisplayers" fields of the solrConfig object. The other configurations options will be the default ones.

  • filterQuery: we limit to items of type DOCUMENT, including a class ERCode.ERClass.
  • facetFields: we add some additional facet fields for the properties of the class ERCode.ERCodeClass. We also remove some fields we don't want from the default configuration.
  • facetDisplays: we declare which facet code to use for each of the fields.

Create the ExpenseReport.Search page with the following content:

{{velocity output="false"}}
#set ($solrConfig = {
  'filterQuery': [
    'type:DOCUMENT',
    'class:ERCode.ERCodeClass'
  ],
  'facetFields': [
    'property.ERCode.ERCodeClass.status_string',
    'property.ERCode.ERCodeClass.organisation_string',
    'property.ERCode.ERCodeClass.currency_string',
    'property.ERCode.ERCodeClass.user_string',
    'author',
    'creator',
    'date',
    'creationdate'
  ],
  'facetDisplayers': {
    'type': 'Main.SolrTypeFacet',
    'wiki': 'Main.SolrWikiFacet',
    'locale': 'Main.SolrLocaleFacet',
    'author': 'Main.SolrUserFacet',
    'creator': 'Main.SolrUserFacet',
    'attauthor': 'Main.SolrUserFacet',
    'date': 'Main.SolrDateFacet',
    'creationdate': 'Main.SolrDateFacet',
    'attdate': 'Main.SolrDateFacet',
    'class': 'Main.SolrClassFacet',
    'attsize': 'Main.SolrFileSizeFacet',
    'mimetype': 'Main.SolrMediaTypeFacet',
    'property.ERCode.ERCodeClass.status_string' : 'ExpenseReport.ListFacet',
    'property.ERCode.ERCodeClass.organisation_string' : 'ExpenseReport.ListFacet',
    'property.ERCode.ERCodeClass.currency_string' : 'ExpenseReport.ListFacet',
    'property.ERCode.ERCodeClass.client_string' : 'ExpenseReport.ListFacet',
    'property.ERCode.ERCodeClass.user_string' : 'Main.SolrUserFacet'
  }
})
{{/velocity}}
{{include reference="Main.SolrSearch" /}}

Facet Code for the List field

We need to provide a code for the facet for list fields, as it is not provided by default in XWiki. Put the following code in the content of ExpenseReport.ListFacet:

{{velocity}}
#macro (displaySearchFacetValue_list $value)
 #set($class = $xwiki.getDocument($pclass).getxWikiClass())
 #set($prop = $class.get($propName))
 ## here we convert the raw value in a nicely displayed value
$prop.getMapValues().get($value).value
#end
#if ($facetValues)
 ## here we extract the class name and field name so that we can avoid hardcoding it
 #set($index1 = $facetField.name.lastIndexOf("."))
 #set($index2 = $facetField.name.lastIndexOf("_"))
 #set($pclass = $facetField.name.substring(0, $index1).substring(9))
 #set($index1 = $index1 + 1)
 #set($propName = $facetField.name.substring($index1, $index2))
  {{html}}
 <ul class="${propName}">
    #displaySearchFacetValuesLimited($facetValues {} 'displaySearchFacetValue_list')
 </ul>
  {{/html}}
#end
{{/velocity}}

Result

Here is the result of our customized SOLR search (from the ExpenseReport.Search page):

customsolrsearch.png

If you want to customize the title of the facet that is displayed in the facet bar, you need to add translations with keys of the following format in a translations file somewhere:

solr.field.<full facet field>

 where full facet field is the facet field id, as it was added in the 'facetDisplayers' map above.

For our example, we'd add new facet titles like this:

solr.field.property.ERCode.ERCodeClass.status_string=Expense report status
solr.field.property.ERCode.ERCodeClass.organisation_string=Expense report organisation
solr.field.property.ERCode.ERCodeClass.currency_string=Expense report currency
solr.field.property.ERCode.ERCodeClass.client_string=Expense report client
solr.field.property.ERCode.ERCodeClass.user_string=Beneficiary

If these translations are not present, the engine will pick-up automatically as facet titles the display names of the properties of the facets.

Get Connected