Sorting collapsed results

Managed by | Updated .

If you choose to display the collapsed results within the initial result set (eg. as a list of sub-results) then you need to be aware of the following.

There currently is no way to get Funnelback to return the set of results in a defined sort order.  However you can sort the results using a Groovy hook script.

The collapsed results returned with the result packet are limited to the first N results as defined by collapsed_num_ranks.  You'll only have access to the first N items (for sorting purposes) so ensure this value is set to an appropriate value.  

The collapsed results will only include items that match the query term (so if you're using it to display child pages, then all the children need to match the query).

The following code can be used to sort the items that are returned as part of the result packet (though only the items returned)

hook_post_process.groovy
if ( transaction.response != null && transaction.response.resultPacket.results != null
        && transaction.response.resultPacket.results.size() > 0 ) {
                  transaction.response.resultPacket.results.each() {
                        if (it.collapsed != null && it.collapsed.results != null && it.collapsed.results.size() > 0) {
                                        Collections.sort(it.collapsed.results, {a, b -> sortCompare(a, b)} as Comparator);
                        }
        }
}
 
def sortCompare(a, b) {
//Define sort overrides - this sets a sort key to use when doing the alphabetic search.  in the example below an item with 'Custom title - show me first' as the field value will be treated as AAAAA000000 for the purposes of sorting.
    def labelOrderMap = [
                         "Custom title - show me first":"AAAAA000000",
                         "Custom title - show me last":"ZZZZZ00000",
                         ];
    def labela = a.title;
    def labelb = b.title;
    if (labelOrderMap.containsKey(labela)) {
        labela = labelOrderMap[labela];
    }
    if (labelOrderMap.containsKey(labelb)) {
        labelb = labelOrderMap[labelb];
    }
    labela.compareTo(labelb);
}

The following code block can be used to sort collapsed results based on two metadata values.

hook_post_process.groovy
if ( transaction.response != null && transaction.response.resultPacket.results != null
        && transaction.response.resultPacket.results.size() > 0 ) {
                  transaction.response.resultPacket.results.each() {
                        //Code block that sorts (in ascending order) collapsed results based on 2 numeric metadata values
                        if (it.collapsed != null && it.collapsed.results != null && it.collapsed.results.size() > 0) {
                                it.collapsed.results.sort{[it.metaData["MinorVersion"], it.metaData["MajorVersion"]]}
                        }
        }
}

When you click on the sorted link it's possible to apply a sort to the resultant query.  Note: to do this you'll need to use a modified collapsed macro e.g.

<#---
 
    Generates a link to show the results that were collapsed with this specific result.
 
    @param defaultLabel Label to use when there's no label for the current collapsing column
    @param labels Text to use for the link. <code>{0}</code> will be replaced by the number of collapsed results. This is a hash where the key is the collapsing column, as a String.
 
-->
<#macro Collapsed sort defaultLabel="{0} very similar results" labels={}>
    <#if s.result.collapsed??>

        <#assign text = defaultLabel />
        <#if labels[s.result.collapsed.column]??>

            <#assign text = labels[s.result.collapsed.column] />
        </#if>
        <a class="search-collapsed" href="?${QueryString}&amp;s=%3F:${s.result.collapsed.signature}&amp;fmo=on&amp;collapsing=off<#if sort?exists>&amp;sort=${sort?html}</#if>">${text?replace("{0}", s.result.collapsed.count)}</a>
    </#if>
</#macro>
Was this artcle helpful?

Tags
Type: Keywords:
Features: Frontend > Freemarker Frontend > Hook scripts

Comments