Meta collection facets

I’ve been looking at using facets on a meta collection that combines a wide range of different collections, but have just read that meta collections dont support a number of facet types.

When I am using facets on a single collection it is mostly the metadata mapping type

Am I correct in thinking this can’t be accessed from a meta collection?

Looking at the example - http://showcase.funnelback.com/s/search.html?collection=showcase-faceted-navigation&profile=_default&query=!showall

Does all this content sit in one collection (rather than a meta)?
Or are all the facets set up manually to pattern match urls?

Hi David,

You can use facets on a meta collection that come from all sorts of sources, including metadata.

You’ll want to make sure the Query Processor Options on the meta collection include the Summary Fields (-SF) of the metadata you wish to create the facets for.

I encourage you to look at the JSON endpoint of the search results (replace html with json in the URL) while you are building and troubleshooting. In the JSON endpoint, the node for each result includes what metadata has been found for that result (according to the Query Processor Options that were set). If you see the metadata you want, then the facet will work.

An example showing facets on a meta collection which contains multiple components (each tab is a different component):
http://showcase.funnelback.com/s/search.html?collection=higher-education-meta

Note that you can even use one facet across multiple components if you’d like, for example, there is one Department facet that you see both on Programs and People.

1 Like

Hi, the faceted navigation limitation for meta collections is only relevant if you are using Funnelback 15.10 or earlier.

Faceted navigation had a major rewrite for 15.12 so if you’re using this version or newer you can use any of the facet types that are offered when configuring faceted navigation.

1 Like

Thank this is very helpful.

Is there Freemarker template code somewhere in the documentation for the ‘Sort by’ and ‘Number of results per page’ drop downs in that example?
I can’t seem to find it anywhere.

Hi David,

There’s an example of how to create a sort mode dropdown in the training. See: http://training-search.clients.funnelback.com/training/FUNL201.html#_exercise_27_create_a_sort_mode_switcher_in_the_template

You would apply a similar logic to the number of results (except you would have the select list on the num_ranks parameter instead of sort).

Thats helpful thank you.

Are there any other code examples that use a url based approach to pass the parameters (like in the HE example above) rather than a form submission?

And is it possible to limit a sort to a specific tab?
So switching to a different tab would default to sort by relevance.

As you noted, since the sort and limit parameters are passed to the URL, you can use either a form-based approach (which sends a GET request including URL parameters in any <input> element) or a hyperlink-based approach which uses an <a> element with the sort parameter passed in.

A code example of the latter can be found in our public repository at:

1 Like

To allow different sorting methods for different tabs, the Freemarker code linked in the Github example can be modified, like this:

<#--
  Generate an HTML drop-down for sorting results

  @param options Map of sort options, where keys are the `sort` paratmeter (e.g. `date`) and values the label (e.g. `Date (Newest first)`)
-->
<#macro SortDropdown>
<#-- People tab -->
  <#if question.inputParameterMap["f.Tabs|higher-education-people"]??>
    <#local options={
      "": "Alphabetical (last name)",
      "dmetapeopleLastName": "Reverse Alphabetical (last name)",
      "metapeopleFirstName": "Alphabetical (first name)",
      "dmetapeopleFirstName": "Reverse Alphabetical (first name)"} >
<#-- Programs/Courses tab -->
  <#elseif question.inputParameterMap["f.Tabs|higher-education-programs"]??>
    <#local options={
      "": "Relevance",
      "title": "Title (A-Z)",
      "dtitle": "Title (Z-A)"} >
<#-- Events tab -->
  <#elseif question.inputParameterMap["f.Tabs|higher-education-events"]??>
    <#local options={
        "": "Date (Oldest first)",
        "date": "Date (Newest first)",
        "title": "Title (A-Z)",
        "dtitle": "Title (Z-A)"} >
<#-- Facebook tab -->
  <#elseif question.inputParameterMap["f.Tabs|higher-education-facebook"]??>
    <#local options={
    "": "Date (Newest first)",
    "adate": "Date (Oldest first)",
    "title": "Title (A-Z)",
    "dtitle": "Title (Z-A)"} >
<#-- All other tabs -->
  <#else>
    <#local options={
      "": "Relevance",
      "date": "Date (Newest first)",
      "adate": "Date (Oldest first)",
      "title": "Title (A-Z)",
      "dtitle": "Title (Z-A)"} >
  </#if>

  <div class="dropdown float-right">
    <button class="btn btn-light btn-sm dropdown-toggle" id="search-sort" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      <#-- If there is no sort parameter, use "" which is the Relevance option -->
      <#-- If the sort parameter isn't in the options hash, use the default value for blank string  -->
      <span class="text-muted">Sort:</span> ${(options[question.inputParameterMap["sort"]!""])!options[""]}
    </button>
    <div class="dropdown-menu" aria-labelledby="search-sort">
      <#list options as key, value>
        <a class="dropdown-item" title="Sort by ${value}" href="${question.collection.configuration.value("ui.modern.search_link")}?${removeParam(QueryString, "sort")}&sort=${key}">${value}</a>
      </#list>
    </div>
  </div>
</#macro>

Note that the tab value looks like “f.Tabs|[collection-name]”. The easiest way to find the tab value is to click on it and look at the URL (the vertical bar will be HTML-encoded).

To default a sorting method for a specific tab, a “hook script” could be written. You can learn more about hook scripts here:

Here’s an example of a hook_pre_process.groovy script that default the sort to different ways depending on which tab is selected.

def q = transaction.question

// Sort by last name if the People tab is selected
if (q.inputParameterMap["f.Tabs|higher-education-people"] && !q.inputParameterMap["sort"]) {
    q.additionalParameters["sort"] = ["metapeopleLastName"]
}

// Sort by ascending date if the Events tab is selected
if (q.inputParameterMap["f.Tabs|higher-education-events"] && !q.inputParameterMap["sort"]) {
    q.additionalParameters["sort"] = ["adate"]
}

// Sort by date if the Social Media tab is selected
if (q.inputParameterMap["f.Tabs|higher-education-facebook"] && !q.inputParameterMap["sort"]) {
   q.additionalParameters["sort"] = ["date"]
}

// Apply sortall=true to achieve proper sorting for partially matching results
q.additionalParameters["sortall"] = ["true"]

The syntax for the sorting options (for example it may be prepended with ‘meta’ or ‘a’) can be found here:

1 Like

This is really helpful and solves most of the issues.

The only outstanding thing is when switching between tabs having already specified a sort order in another tab.

Eg.
Ordered by date on a news tab but clicking on people tab I want it to remove the sort attribute and default to sorting by relevance.

Is there a way to remove the Sort attribute from the tab links?
Ie.

<a href="${value.toggleUrl}">

You could try using the <@s.RemoveParams> macro: see Modern UI util functions - Funnelback Documentation - Version 15.24.0

Note: it operates on the query string so it may be necessary to split your URL first so it’s just passed the query string portion of your URL).

Thanks

I got a working version by building the tab urls manually rather than using the built in toggleUrl() function.

${question.collection.configuration.value(“ui.modern.search_link”)}?${removeParam(QueryString,question.selectedCategoryValues?keys + [“start_rank”] + [“sort”])}&f.Collection|collection-name-xyz=xyz

So stripping off all facets, pagination and sorting before adding the tab/collection I need