The <panl_collection_url>.panl.properties Configuration File

The <panl_collection_url>.panl.properties file defines which Solr fields will be available on this URL path, how they are configured, sorted, and included in the facets and results.

The mechanical-pencils.panl.properties file is used as the reference material for the configuration options explained in this section. The file is included in the release package, or, for an overly commented online format:

https://github.com/synapticloop/panl/blob/main/src/dist/sample/panl/mechanical-pencils/mechanical-pencils.panl.properties 

Note: The above link is for the most up-to-date file, including new feature developments.  To view the file for the version that you are using, use the tag that matches the version that you are using and download and view the source code. See https://github.com/synapticloop/panl/tags for the version that you are using.


Notes: the <panl_collection_url> part of the file name is the name of the Panl server URL path to bind to and the configuration properties for this URL path. In this book we will be using the Solr collection of mechanical-pencils, bound to a URL path of /mechanical-pencils/* consequently the properties file is named:
mechanical-pencils.panl.properties.


Parameter and Operand Definitions

panl.param.query

The LPSE code for the search query from the user - i.e. for the HTML form below:

01

02

03

04

<form method="GET">

  <label><input type="text" name="search" /></label>

  <button type="submit">Search</button>

</form>

If the user enters a search query of hexagonal - this will be sent to the Panl server as

/mechanical-pencils/brandandname/?search=hexagonal

Which will generate a canonical URL path as - note the LPSE code is 'q'.

/hexagonal/q/

Notes: You can set the parameter key that Solr will use for the search query with the panl.form.query.respondto property (which is 'q' by default).



panl.param.sort

The sort fields and the order for the results to be returned.  The sorting of the results is all contained within the LPSE URL path part, and is encoded by:

  1. The sort LPSE code - i.e. 's'
  2. The facet or field LPSE code e.g. 'b' (for 'Brand'), or 'N' (for 'Pencil Model')
  3. The sort order,  '-' for descending, '+' for ascending

For the following URL path part

/mechanical-pencils/brandandname/sb-sN+/

The results will be sorted by:

  1. brand  (i.e. the 'b' LPSE code) in descending order (the '-' sort order code), then by
  2. name (i.e. the 'N' LPSE code) in ascending order (i.e. the '+' sort order code).

Note: The sort LPSE code does not have a URL path part.

panl.param.page

The page number of the results to be shown on the page, which also allows both a prefix and suffix. To define a prefix, configure the panl.param.page.prefix property, to define a suffix, configure the panl.param.page.suffix property.

With the following properties defined:

01

02

03

panl.param.page=p

panl.param.page.prefix=page-

panl.param.page.suffix=-shown

The generated URL path part will be generated as:

/mechanical-pencils/brandandname/page-1-shown/p/

The Solr search server does not have an implicit idea of pagination, it has a start parameter which is the offset of the number of documents and a numrows parameter which determines the number of documents to return for a query.

The Panl server translates this, in conjunction with the panl.paramn.numrows property, to the correct starting offset for the documents in the Solr Query.  In effect the number of results per page (numrows) multiplied by the page number sets the start parameter for the Solr search query.

Additionally, the Panl server validates the passed in page number to ensure that it is a positive integer value.  If the value cannot be parsed or validated, the page number is set to 1 (i.e. the Solr start query parameter is set to 0).

Example:

The following will return all 55 results, on page 1 and showing 10 results per page

http://localhost:8181/panl-results-viewer/mechanical-pencils/brandandname/page-1/10-per-page/pn/

The Solr query is:

q=*:*&q.op=OR&facet.limit=100&fl=brand,name&facet.mincount=1&rows=10&facet.field=lead_size
_indicator&facet.field=colours&facet.field=brand&facet.field=mechanism_type&facet.field=id
&facet.field=hardness_indicator&facet.field=in_built_sharpener&facet.field=disassemble&fac
et.field=category&facet.field=lead_length&facet.field=in_built_eraser&facet.field=grip_sha
pe&facet.field=weight&facet=true&start=0

Note the Solr query start parameter of 0 (i.e. start=0) which is expected as the offset is 0 from the start of the results.  For the second page

http://localhost:8181/panl-results-viewer/mechanical-pencils/brandandname/page-2/10-per-page/pn/

q=*:*&q.op=OR&facet.limit=100&fl=brand,name&facet.mincount=1&rows=10&facet.field=lead_size
_indicator&facet.field=colours&facet.field=brand&facet.field=mechanism_type&facet.field=id
&facet.field=hardness_indicator&facet.field=in_built_sharpener&facet.field=disassemble&fac
et.field=category&facet.field=lead_length&facet.field=in_built_eraser&facet.field=grip_sha
pe&facet.field=weight&facet=true&start=10

The Solr query has a start parameter of 10 (i.e. start=10).  In effect the start parameter is calculated by Panl as (page_number - 1) * num_rows.

panl.param.numrows

The number of results shown on the page, which also allows both a prefix and suffix. To define a prefix, configure the panl.param.numrows.prefix property, to define a suffix, configure the panl.param.numrows.suffix property.

01

02

03

panl.param.numrows=n

panl.param.numrows.prefix=display-

panl.param.numrows.suffix=-per-page

The generated URL path part will be generated as:

/mechanical-pencils/brandandname/display-1-per-page/n/

panl.param.query.operand

This LPSE code defines the query operand to be passed through to the Solr server, and only has one of two possible values.  Like the sort LPSE code, this query operand LPSE code does not have a URL path part.

The query operand URL parameter that the Solr server responds to to determine whether the search term should be found in any one of the Solr analysed fields (OR), or all of the analysed fields (AND).

The following URL Path part will search for the 'hexagonal' keyword and return results that are in in ALL of the analysed search fields

/mechanical-pencils/brandandname/hexagonal/qo+/

Whilst this URL path below will will search for the 'hexagonal' keyword and return results that are in in ANY of the analysed search fields

/mechanical-pencils/brandandname/hexagonal/qo-/

Note: The query operand LPSE code does not have a URL path part

By default the query operand is set to OR as it will return the most results.

panl.param.passthrough

This LPSE code is used purely for generating SEO friendly URLs and is not passed through to the Solr Search server.  The passthrough parameter should be used with other parameters that help to filter the results.

01

panl.param.passthrough=z

For example, the following URL path parts will return exactly the same results (in fact all of the results as there are no other facets applied):

/lots-of-mechanical-pencils/z/

/the+best+mechanical+pencils/z/

The above two paths would generate the same canonical URL of

/

However, you could also define multiple URL path parts to return pencils manufactured by BIC with the following URL path.

/the+finest+selection+of+BIC+mechanical+pencils/BIC/zb/

Note that the above URL path could also have been generated by using a prefix and suffix  without the trailing /BIC/, however this would have meant that if this was set to an OR facet, then the length of the URL path would grow very quickly.

Note: The passthrough LPSE code will __NOT__ be included in the canonical URL generation unless the panl.param.passthrough.canonical is set to true. (see below.

panl.param.passthrough.canonical

Whether the LPSE code for a passthrough parameter will be used to generate the canonical URL.

01

panl.param.passthrough.canonical=false

If set to true, the URL path value will still not be used as a filter for the Solr query, it will not be sent to the Solr server, and will therefore not affect the results, HOWEVER it will be part of the canonical URL path.

This allows the URL path to have arbitrary text for readability without affecting the outcome.

For example, if the value of this property (i.e. the LPSE code) is set to z then the following URL paths will return the exact same search results.

/cuddly-brown-teddy-bears/z/

/motor-vehicles-with-three-wheels/z/

For the above URL paths, the generated canonical URL paths will (respectively) be

/cuddly-brown-teddy-bears/z/

/motor-vehicles-with-three-wheels/z/

This can be useful when generating a SEO friendly URL which doesn't require any more faceting.  For example if a URL is generated that references a unique ID of a product (which will only return one result) this mechanism can be used to ensure a friendly canonical URL path.

For example, the URL

http://localhost:8181/panl-results-viewer/mechanical-pencils/brandandname/53/i/ 

Will return only one result - the Staedtler 925 pencil.

The URL path of /53/i/ is not that exciting, so a passthrough parameter of Staedtler-925-Metal-Pencil-in-blue,black,or silver colours could be added for more informational URL paths.

http://localhost:8181/panl-results-viewer/mechanical-pencils/brandandname/Staedtler-925-Metal-Pencil-in-blue,black,or+silver+colours/53/zi/

/Staedtler-925-Metal-Pencil-in-blue,black,or+silver+colours/53/zi/

This would return the same result, however the canonical URL path would be:

/53/page-1/10-per-page/ipn/

With this panl.param.passthrough.canonical property set to true, the canonical URL path becomes

/Staedtler-925-Metal-Pencil-in-blue%2Cblack%2Cor+silver+colours/53/page-1/10-per-page/zipn/

This is done on a wide range of large sites, including e-commerce sites to boost SEO ratings.

Tips: It is recommended to have a separate CaFUPs file for each of these usages as there is no need to define or return any facets for this page as there is only one result.

panl.form.query.respondto

When the user submits a search query, this is the URL parameter key that Panl will use as the search phrase.  With the property set to 'search' in the following line

panl.form.query.respondto=search

01

02

03

04

<form method="GET">

  <label><input type="text" name="search" /></label>

  <button type="submit">Search</button>

</form>


For the above HTML form,
Panl will use the URL parameter 'search' value as the keyword search.  This does not affect the LPSE code, which is set to 'q' for URL generation.

panl.include.single.facets

Facets that only include a single result to further refine the query will not be included by default.  The reasoning behind this is that having a list of facets with only one result will not refine the query at all, it will simply return the same set of results, just with a longer LPSE URL.  You may wish to include these results for a more verbose URL and possibly better search engine visibility.

The default value for this property is false, so you do not need to include it unless you wish to enable this feature, i.e.

        panl.include.single.facets=true

panl.include.same.number.facets

Facets that include the same number of results as the number of documents that are returned will not be included by default.  The reasoning behind this is that if, by using this facet, you will get exactly the same results, then this is not a refinement of the query at all, it will simply return the same set of results, just with a longer LPSE URL.

The default value for this property is false, so you do not need to include it unless you wish to enable this feature, i.e.

panl.include.same.number.facets=true

For example:

The link:

http://localhost:8181/panl-results-viewer/mechanical-pencils/brandandname/Manufactured+by+Koh-i-Noor+Company/Green/Cylindrical+Grip/120mm/bWGL/

Shows 3 results and returns the following in the available filters section

Colours (W)

Note: that there are no Blue or Red facet values returned

Notes: For the links below, this property is set to false in the provided example file, you will need to manually edit the mechanical-pencils.panl.properties file and set this to true for the example to work.


With this property set to true (i.e. panl.include.same.number.facets=true) then the results

http://localhost:8181/panl-results-viewer/mechanical-pencils/brandandname/Manufactured+by+Koh-i-Noor+Company/Green/Cylindrical+Grip/120mm/bWGL/ 

Show 3 results, and include within the available filters section

 Colours (W)

Note that the values of the Colours Blue (3) and Red (3) are both 3, which match the number of returned documents.

Clicking on either of those (or both in either order) will generate URL paths which return identical results:

All of the above three links add additional LPSE path encodings, without filtering the results any further, thus offering little value to users who would like to refine their results further.

Should you wish the above scenario to be the case, then set this value to false.

solr.default.query.operand

This maps to the Solr q.op parameter, by default it is OR which - i.e. the search query will need to be in one of the search fields.  This is only used for keyword searches, not facets.

solr.facet.limit

The maximum number of facet values to return for any particular facet - By default this is set to 100.  

solr.facet.min.count

The minimum facet count to return, if the facet count is less than this, then the facet value will not be returned.  By default, this is set to 1.

solr.numrows.default

The number of results to return for the search.  By default this is 10, but may be any positive integer.

solr.highlight

Whether to return highlighting information in the JSON response object. If set to true an additional JSON Object will be added to the root JSON object named 'highlighting'.  This object then has key value pairs keyed on  the 'id' Solr field (i.e. the <uniqueKey /> XML element in the managed schema file) with the value of the Solr field where this highlighting occurs.

Field Definitions

Fields do not filter the search results, but are used to have them returned with each document.  Additionally, field definitions allow Panl to be configured to use them as a sort order.

A Panl field is configured by setting a key within the properties file and will ALWAYS have the form of:

panl.field.<lpse_code>=<solr_field_name>

Where:

  • <lpse_code>  is the assigned LPSE code as either a letter or a number.  The number of characters (either letters or numbers) in the <lpse_code> MUST match the value of the panl.lpse.length property.

    For example: If the property
    panl.lpse.length=1, then each <lpse_code> must be 1 alphanumeric character long, if panl.lpse.length=2, each <lpse_code> must be 2 alphanumeric characters long.
  • <solr_field_name> is the case-sensitive name of the field that is defined in the Solr search schema configuration. This MUST match the Solr field name.

Properties Available for Facets

The following properties are available for any facet that is defined, however there are additional properties available depending on the type of the Solr field and whether  the field is configured to be a RANGE, OR, BOOLEAN, or DATE Range facet.

  • panl.field.<lpse_code>=<solr_field_name>

    MANDATORY property to indicate to Panl that the named Solr field is to be used as a field in Panl.

    If this property does not exist, then this Solr field and LPSE code will not be registered, and all other properties will be ignored.
  • panl.name.<lpse_code>=<nicer_name_for_the_field>

    Optional property to display a nicer name than the Solr field name.

    If this property does not exist, or is a blank or empty string, then the
    <solr_field_name> from the above property will be used instead.
  • panl.type.<lpse_code>=<truncated_solr_java_class_name>

    Optional property of the base Solr field type, this property is set automatically by the Panl configuration generator.

    This property is not used by a Panl field, however it is a good idea to keep this property in case you wish to use it as a facet in a further iteration.

IMPORTANT: This property should __NEVER__ change, __UNLESS__ the underlying Solr managed schema has changed.


Facet Definitions

Facets (along with the query parameter) refine the search results, however, unlike the query parameter, there are additional configuration items that will affect the URL path part that is displayed to the user.

A Panl facet is configured by setting a key within the properties file and will ALWAYS have the form of:

panl.facet.<lpse_code>=<solr_field_name>

Where:

  • <lpse_code>  is the assigned LPSE code as either a letter or a number.  The number of characters (either letters or numbers) in the <lpse_code> MUST match the value of the panl.lpse.length property.

    For example: If the property
    panl.lpse.length=1, then each <lpse_code> must be 1 alphanumeric character long, if panl.lpse.length=2, each <lpse_code> must be 2 alphanumeric characters long.
  • <solr_field_name> is the case-sensitive name of the field that is defined in the Solr search schema configuration. This MUST match the Solr field name.

IMPORTANT: Any property in the <panl_collection_url>.panl.properties file that starts exactly with panl.facet. is configured to be a facet field in Panl.


Panl supports the following subtypes of facets

  1. Regular Facet
  2. BOOLEAN Facet
  3. OR Facet
  4. RANGE Facet
  5. DATE Range Facet

Properties Available for Facets

The following properties are available for any facet that is defined, however there are additional properties available depending on the type of the Solr field and whether  the field is configured to be a RANGE, OR, BOOLEAN, or DATE Range facet.

  • panl.facet.<lpse_code>=<solr_field_name>

    MANDATORY property to indicate to Panl that the named Solr field is to be used as a faceted result in Panl.

    If this property does not exist, then this Solr field and LPSE code will not be registered, and all other properties will be ignored.
  • panl.name.<lpse_code>=<nicer_name_for_the_field>

    Optional property to display a nicer name than the Solr field name.

    If this property does not exist, or is a blank or empty string, then the
    <solr_field_name> from the above property will be used instead.
  • panl.type.<lpse_code>=<truncated_solr_java_class_name>

    Optional property of the base Solr field type, this property is set automatically by the Panl configuration generator.

    This property drives the validation of incoming requests, and if the base Solr field type is
    solr.BoolType, this will enable the panl.bool.<lpse_code>.true and panl.bool.<lpse_code>.false property lookups.

IMPORTANT: This property should __NEVER__ change, __UNLESS__ the underlying Solr managed schema has changed.

  • panl.prefix.<lpse_code>

    Optional property of arbitrary text value to prefix the Solr field value with.

    For example, if this property is
    panl.prefix.<lpse_code>=This is the prefix  then the display of this value in the URL (encoded) would be:

    /This+is+the+prefix+<solr_field_value>/

    This property value is also returned in the response object for optional use when displaying the list of active and available facets.
  • panl.suffix.<lpse_code>

    Optional property of arbitrary text value to prefix the Solr field value with.

    For example, if this property is
    panl.suffix.<lpse_code>=\ suffixed here then the display of this value in URL encoded form would be:

    /<solr_field_value>+suffixed+here/

    This property value is also returned in the response object for optional use when displaying the list of active and available facets.
  • panl.or.facet.<lpse_code>

    Optional property which enables this facet to be an OR facet - i.e. multiple values can be selected for this facet.

    This property is useful if you want users to be able to select a facet value, or another facet value.

    For example, you may want to allow users to be able to see pencils that were manufactured by Caran d'Ache
    OR Faber-Castell.  The normal functionality would be that the user sees either of the brands, not both.

IMPORTANT: Unlike other facet selections, this will INCREASE the number of documents returned from the Solr server.

  • panl.when.<lpse_code>=<comma_separated_list_of_lpse_codes>

    Referred to as a hierarchical facet, this property defines whether this facet will be shown.  This facet will only be returned by the Panl server if one of the LPSE codes in the
    <comma_separated_list_of_lpse_codes> has already been selected.
  • panl.facetsort.<lpse_code>=<index_or_count>

    By default Solr will return the facets sorted by the count, if you would like Solr to return the results by index (i.e. the value) then set this property.

Regular Facet

A regular facet allows you to select a specific value to refine your search results.  The returned results will all documents that have this facet value.

Prefixes and suffixes are available for regular facets, with the following URL paths returning equivalent results, depending on whether a prefix, a suffix, neither, or both are configured.

  • /Caran+d'Ache/b/ -  Neither prefix nor suffix configured
  • /Manufactured+by+Caran+d'Ache/b/ -  Only a prefix is configured
  • /Caran+d'Ache+Company/b/ -  Only a suffix is configured
  • /Manufactured+by+Caran+d'Ache+Company/b/ -  Both a prefix and suffix is configured

For this example, the brand Solr field will be used with a LPSE code of b.  The definition in the mechanical-pencils.panl.properties file is as follows:

01

02

03

04

05

06

# <field "indexed"="true" "stored"="true" "name"="brand" "type"="string" ↩
        "multiValued"="false" />

panl.facet.b=brand

panl.name.b=Brand

panl.type.b=solr.StrField

panl.prefix.b=Manufactured by

panl.suffix.b=\ Company

Example



Image:  The Panl Results Viewer web app showing the facet with the prefix and suffix applied.  


The text
Brand (b) is the name of the available facet, (derived from the panl.name.b=Brand property) and the  <lpse_code>.

For each of the available values, the [add] link is displayed, followed by the prefixed and suffixed value, with the number of results in parentheses.

Clicking on any of the links will refine the search by only including those documents which have the particular brand.

The URL path

/Manufactured+by+Mitsubishi+Company/b/

Will have the prefix and suffix removed to return the result Mitsubishi which will then be passed on to the Solr search server.

Decoding the URL

Without too many configuration options for a regular facet, the URL is straightforward to decode.  

  1. The LPSE code is looked up to resolve to the brand Solr facet field
  2. The prefix and suffix is stripped from the URL path value
  3. The field value is then passed through to the Solr query

/

Manufactured+by+

Mitsubishi

+Company

/

b

/

This is the prefix

This is the field value

This is the suffix

The LPSE code

URL Path Value

IMPORTANT: If the prefix and/or suffix does not __EXACTLY__ match the defined values, then this value is marked as invalid and __IS_NOT__ passed through to the Solr search query.

BOOLEAN Facet

A BOOLEAN facet works exactly as per a regular facet, however, by definition, there are only two values that it can be, either true, or false.  You select a value to refine your search results to return only those documents which contain this value. For this example, the brand Solr field will be used with a LPSE code of D.  The definition in the mechanical-pencils.panl.properties file is as follows:

01

02

03

04

05

06

# <field "indexed"="true" "stored"="true" "name"="disassemble" "type"="boolean" ↩ "multiValued"="false" />

panl.facet.D=disassemble

panl.name.D=Disassemble

panl.type.D=solr.BoolField

panl.bool.D.true=able to be disassembled

panl.bool.D.false=cannot be disassembled

Additional Properties

  • panl.bool.<lpse_code>.true

    Optional property that defines the replacement value for a 'true' value from the Solr server.

    For example, if this property is
    panl.bool.<lpse_code>.true=Has an extended warranty and the returned Solr field value is 'true' then the display of this value in URL encoded form would be:

    /Has+an+extended+warranty/D/

IMPORTANT: This property is only used if the property  panl.type.<lpse_code>=solr.BoolField, in all other cases these fields will be ignored.

  • panl.bool.<lpse_code>.false

    Optional property that defines the replacement value for a false value from the Solr server.

    For example, if this property is
    panl.bool.<lpse_code>.false=No warranty and the returned Solr field value is 'false' then the display of this value in URL encoded form would be:

    /No+warranty/D/

IMPORTANT: This property is only used if the property  panl.type.<lpse_code>=solr.BoolField, in all other cases these fields will be ignored.

Example



Image:  The Panl Results Viewer web app showing the BOOLEAN facet with value replacement.  


The text Disassemble (D) is the name of the available facet, (derived from the panl.name.D=Disassemble property) and the  <lpse_code>.

For each of the available values, the [add] link is displayed, followed by the boolean replacement value, with the number of results in parentheses.

The URL path

/able+to+be+disassembled/D/

Will look up the true/false values and if it matches, will pass on this true/false value on to the Solr search server.

IMPORTANT: If the value does not exactly match the true or false replacement values, then this will be marked as invalid and will not be passed through to the Solr search server.


Decoding the URL Without a Prefix or Suffix

In the case of a true value, the URL path would be:

  1. The LPSE code is looked up to resolve to the disassemble Solr field
  2. The value is looked up and if it exactly matches
  3. The field value is then passed through to the Solr query

/

able+to+be+disassembled

/

D

/

This is a boolean replacement value that will be looked up - in this case, it is the true value

The LPSE code

URL Path Value

In the case of a false value, the URL path would be and would go through the same decoding process as the true value.

/

cannot+be+disassembled

/

D

/

This is a boolean replacement value that will be looked up - in this case, it is the false value

The LPSE code

URL Path Value


Defining a Prefix and Suffix

Prefixes and suffixes are also available for a boolean facet.  Lines 5 and 6 of the above configuration (shown below)

05

06

panl.bool.D.true=able to be disassembled

panl.bool.D.false=cannot be disassembled


Could be replaced with the following three lines, and would have an identical effect, however the decoding of the URL path value would be different.

04

05

06

panl.bool.D.true=able to be

panl.bool.D.false=cannot be

panl.suffix.D=\ disassembled


Decoding the URL With a Prefix or Suffix

  1. The LPSE code is looked up to resolve to the disassemble Solr facet field
  2. The suffix is removed from the URL path value
  3. The lookup value is checked and if found, and exactly matches the defined property, then this token is marked as valid
  4. If the token is valid, then field value is then passed through to the Solr query

/

able+to+be

+disassembled

/

D

/

This is the lookup value

This is the suffix

The LPSE code

URL Path Value

IMPORTANT: If the prefix and/or suffix and/or lookup for the boolean values do not exactly match the defined values, then this value is marked as invalid and not passed through to the Solr search query.

OR Facet

An OR facet allows the user to select multiple values for the same facet, where a document only has a single value for this facet.  This is different to a multivalued Solr field as this field allows the user to select multiple facet values for a specific document, when the document has only one of them assigned..

Additional Properties

  • panl.or.facet.<lpse_code>=<true_or_false>

    This configures Panl to use this facet as an OR facet.  By default it is set to '
    false', setting this property to 'true' enables this facet as an OR facet.

The Difference Between Multi-valued Facets and OR Facets

Multi-values Facets

Multi-valued facets are Solr field definitions which may have multiple values for a specific field. When selected, the multi-valued facet field may still return values, provided that, within the selected documents, they also have other facet values that could further refine the results.

As an example,

  • a pencil may come in a range of colours.
  • it may a range of specific variants,
  • it may be suitable for a wide range of applications

In the colours field definition for the mechanical-pencils schema is multivalued, each pencil can have one or more colours.

01

# <field "indexed"="true" "stored"="true" "name"="colours" "type"="string" ↩

         "multiValued"="true" />

Consider pencils that have a "Brown" colour:

http://localhost:8181/panl-results-viewer/mechanical-pencils/brandandname/Brown/W/

Which returns 4 results (Manufacturer // Pencil model):

  1. OHTO // Maruta
  2. Koh-i-Noor // 5217
  3. Mitsubishi // Uni
  4. Pacific Arc // Tech Pro

There are still additional colours to further facet by:

  • Red (3)
  • Black (2)
  • Blue (2)
  • Green (2)
  • Orange (1)
  • Pink (1)
  • White (1)
  • Yellow (1)

Which means that within the brands and model names of the pencils, some of the pencils within the four results also come in additional colours than just the 'Brown' that was selected.



Image:  A selection of four brands and their associated colours - with at least one model within the Brand that comes in a 'Brown' colour


If the colour 'Blue' is then further selected:

http://localhost:8181/panl-results-viewer/mechanical-pencils/brandandname/Brown/Blue/WW/

Only two results will be returned:

  1. Koh-i-Noor // 5217
  2. Pacific Arc // Tech Pro

Now we have a list of pencil models that come in both 'Brown' and 'Blue' colours (e.g. you could purchase a Koh-i-Noor pencil, model 5217 in one of the two colours).

Each selection of the multi-valued attributes on the document further refines the search criteria - the selection selects documents (i.e. mechanical pencils) that come in both 'Blue' AND 'Brown' colours.

Contrast this with an OR facet, which, as the name suggests would make this an OR query between the facet.

Tip: Multivalued Solr fields work best as Regular facets.


OR Facets

OR facets are based on Solr field definitions which can only have singular values - i.e the field definition has the attribute of "multiValued"="false". For example,

  • a pencil can only be manufactured by a single company,
  • a pencil will only weight one value,
  • it will only be of a certain length,
  • etc.

And then allow the user to select another value from this single-valued facet.

IMPORTANT: For the links in this section to work, you will also need to have configured the panl.properties file to include the mechanical-pencils-or.panl.properties in the sample directory.

01

# <field "indexed"="true" "stored"="true" "name"="brand" "type"="string" ↩

         "multiValued"="false" />


If you select a facet from a single value Solr field, then it will only return documents that contain this value. As it is not multi-valued, this facet will no longer be returned with any values from the Solr server.

For example, a pencil may only be manufactured by one company, so if you were to select the manufacturer 'Faber-Castell', only pencils that were manufactured by this brand would appear and no other brands would be returned in the facet.

However, in some instances, you may want to increase the number of documents that are returned by allowing the user to select multiple manufacturers, this is where an OR facet can be used.

Notes: The example below is not from the mechanical-pencils.panl.properties file, but is from a separate file, edited so that the prefix and suffix have been removed for clarity


If you want to allow users to be able to see pencils from multiple manufacturers - e.g. pencils that were manufactured by Caran d'Ache OR Faber-Castell.  
(The normal functionality would be that the user would only see either of the brands, not both.)

01

02

03

04

# <field "indexed"="true" "stored"="true" "name"="brand" "type"="string" ↩
        "multiValued"="false" />

panl.facet.b=brand

panl.or.facet.b=true

panl.name.b=Brand


Example

http://localhost:8181/panl-results-viewer/mechanical-pencils-or/firstfive 

A screengrab of the 'Brand' and 'Colours' facets are shown below.  As the brand Solr field was configured to be an OR facet, the JSON object returns a key of is_range_facet, and the Panl Results Viewer web app is configured to suppress the rendering of the facet count for this facet.

Notes: The count of the Brand facets are still available in the returned JSON Object, they are just suppressed in the rendering of the page by the Panl results viewer web application.  This is done as when no brand is selected, the count of the values for the facet would normally indicate to the user how many pencils of each brand there are.

However, when one Brand facet is selected, the values for all other Brand facets will display 0 (zero) - which makes sense, as you cannot have a pencil that belongs to two Brands at once.


With no query or facets added, there are 55 results in the results set.



Image:  The Brand and Colours facets, showing all Brands (without the facet count) and Colours.

Selecting the first OR facet value

http://localhost:8181/panl-results-viewer/mechanical-pencils-or/firstfive/Koh-i-Noor/b/ 

Upon selecting a brand (in this instance 'Koh-i-Noor'), the Colours facet will now show the values for all mechanical pencils for this Brand - Note that the colour Black has now only 6 values (as opposed to the 31 available above).

There are only 11 results (out of the 55) that are of the selected brand.



Image:  Selecting the first facet 'Koh-i-Noor'


Normally, the 'Brand' facet would not be returned and consequently not displayed.  As this is set to an OR facet, the user could now select another brand to broaden the search.

Selecting the second OR facet value

http://localhost:8181/panl-results-viewer/mechanical-pencils-or/firstfive/Koh-i-Noor/Alvin/bb/



Image:  Selecting the second facet 'Alvin'


Note that the number of results has increased (from 11 to 14) and the count of the facet values has also increased (the colour Black remains the same, however the Blue count has increased from 7 to 10).  Or facets may also increase the selections for other facets.

In effect, the query for Solr is requesting any result documents that have the Brand of 'Koh-i-Noor' OR 'Alvin'.

Decoding the URL

/Koh-i-Noor/Alvin/bb/

  1. The LPSE codes are looked up to resolve to the brand Solr facet field - there are two, both b
  2. The first and second values are retrieved
  3. The fields are passed through to the Solr server as an OR query:
    fq=brand:("Koh-i-Noor"+OR+"Alvin")

/

Koh-i-Noor

/

Alvin

/

bb

/

This is the first field value

This is the second field value

The LPSE code

URL Path Value

Tips: See The "available.facets" JSON Object - Implementation notes section for details about rendering the information and generating URL paths

RANGE Facet

RANGE facets are the most complex of facets with the most configuration options.

A range facet selects an inclusive range of values to refine the search results such that the results only return those documents which contain a value that lies within this range.

Notes: RANGE facets are __ALWAYS__ returned in every query, additionally, the Panl server __WILL__ return the regular facet and values in the JSON response Object.

This allows you to choose whether to display the range facet or the regular facet.


For this example, the
weight Solr field will be used with a LPSE code of w.  The definition in the mechanical-pencils.panl.properties file is as follows:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

# <field "indexed"="true" "stored"="true" "name"="weight" "type"="pint" ↩

         "multiValued"="false" />

panl.facet.w=weight

panl.name.w=Weight

panl.type.w=solr.IntPointField

panl.suffix.w=\ grams

panl.range.facet.w=true

panl.range.min.w=10

panl.range.max.w=50

panl.range.prefix.w=weighing from

panl.range.infix.w=\ to

panl.range.suffix.w=\ grams

panl.range.min.value.w=from light

panl.range.max.value.w=heavy pencils

panl.range.min.wildcard.w=true

panl.range.max.wildcard.w=true


Additional Properties

  • panl.range.<lpse_code>=<true_or_false>

    This property sets this facet as being a RANGE facet, the default property value for this is
    false.

    Optional property which enables this facet (when set to 'true') to be a RANGE facet - i.e. the Solr search will include a range from a value, to another value.

IMPORTANT: Whilst Solr supports range facets on nearly all field types, only Solr field types of numbers are fully supported in Panl.

  • panl.range.min.<lpse_code>=<integer_or_decimal>

    MANDATORY IF panl.range.<lpse_code>=true The minimum value to set the range slider to[17] - this must be a number (either integer or decimal)
  • panl.range.max.<lpse_code>=<integer_or_decimal>

    MANDATORY IF panl.range.<lpse_code>=true The maximum value to set the range slider to[18] - this must be a number (either integer or decimal)
  • panl.range.prefix.<lpse_code>=<text_to_prefix_with>

    Optional property to prefix the range with, this is distinct from the
    panl.prefix.<lpse_code> property and changes the way in which the URL is generated.
  • panl.range.infix.<lpse_code>=<text_infix_between_values>

    Optional property to place between the ranges, if set this will also affect the way in which the LPSE URL path is generated.  If this is not set it will default to the tilde character '
    ~'

IMPORTANT: It is __NOT__ recommended that a hyphen/minus sign (i.e. '-') is configured for the infix.  Depending on the other configuration options, this may be confused for a negative value.

  • panl.range.suffix.<lpse_code>=<text_to_suffix_with>

    Optional property to suffix the range with with, this is distinct from the
    panl.suffix.<lpse_code> property and changes the way in which the URL is generated.
  • panl.range.min.value.<lpse_code>=<text_to_replace_minimum_value>

    This property sets a replacement String for the minimum value of the range, which allows generating a friendlier URL.
    Note: You will still be able to use the minimum range value, this is just an additional nicety for SEO friendlier URLs.

  • panl.range.max.value.<lpse_code>=<text_to_replace_maximum_value>

    This property sets a replacement String for the maximum value of the range, which allows generating a friendlier URL.
    Note: You will still be able to use the maximum range value, this is just an additional nicety for SEO friendlier URLs.
  • panl.range.min.wildcard.<lpse_code>=<true_or_false>

    Set whether to have a wildcard replace the minimum value when sending the query through to the Solr server. Setting this property to '
    true' means that the minimum value also includes any values that are less than it.
  • panl.range.max.wildcard.<lpse_code>=<true_or_false>

    Set whether to have a wildcard replace the maximum value when sending the query through to the Solr server.  Setting this property to '
    true' means that the maximum value also includes any values that are greater than it.
  • panl.range.suppress.<lpse_code>=<true_or_false>

    Set whether the individual range values should be suppressed.  By default, Panl will return the available range facet, in the
    available.range_facets JSON array and also return the individual values in the available.facets JSON array.  Setting this to 'true' will not return the individual facets, only the range facets.

Visualising the Properties

Below is a diagram of what results will be included depending on the properties that are configured.



Image:  How the properties affect the values that the Solr search will include


For the above range searches

  1. For any default range search (in this case the search is 10 to 40), Panl will include both values - i.e. the search will select values greater than or equal to 10 and less than or equal to 40
  2. For a search for the minimum value (panl.range.min.value.<lpse_code>) to 40, Panl will include all values greater than or equal to 5 and less than or equal to 40.
  3. With the panl.range.min.wildcard.<lpse_code> property set, and the minimum value range search, Panl will return all results that are less than or equal to 40, with no lower bound.

Having the minimum/maximum range properties allows documents that are added post configuration that would fall outside of the range to be included. For example, if your min/max range properties were set to 5 and 100, without the wildcard properties, and a new document was added with the value 105, this document would never be able to be selected with the range filter.  With the panl.range.max.wildcard.<lpse_code> property set, it would automatically be included.

Tips: It is prudent to set both the panl.range.min.wildcard.<lpse_code> and panl.range.max.wildcard.<lpse_code> properties to true.


When a RANGE facet is defined, a new heading of 'Range Filters' will appear in the Panl Results Viewer between the 'Active Filters'  an 'Available Filters'.



Image:  The rendered RANGE facet


The implementation in the Panl Results Viewer web app has all of the logic for the display of the range values including minimum and maximum value replacements.

Decoding the URL - Range facet with an infix

/weighing+from+16+to+42+grams/w-w/

/

weighing+from+

16

+to+

42

+grams

/

w-w

/

This is range prefix

This is the from value

This is the range infix

This is the to value

This is the range suffix

The LPSE code

URL Path Value


Decoding the URL - Range facet without an infix

/

weighing+from+

16

~

42

+grams

/

w+w

/

This is range prefix

This is the from value

This is the to value

This is the range suffix

The LPSE code

URL Path Value

Note that a RANGE facet with an infix uses the LPSE code w-w, whereas a RANGE facet without an infix uses the LPSE code w+w - note the plus versus minus signs.

DATE Range Facet

Date range facets are only available on Solr field types of solr.DatePointField and for any of these field types, DATE Range facets will be enabled.

IMPORTANT: If the Solr field type is solr.DatePointField, then the __ONLY__ type of facet that Panl supports is the DATE Range facet.


Because
solr.DatePointField are always returned as DATE Range facets by Panl, new  fields were derived from the solr_date field for users to facet on, these are included in the XML example below.  For the simple-date sample (in the /sample/solr/simple-date/managed-schema.xml file) the field definitions are:

01

02

03

04

05

06

<field name="solr_date" type="pdate" indexed="true" stored="true" ↩

       multiValued="false" />

<field name="text_date" type="string" indexed="true" stored="true" ↩

       multiValued="false" />

<field name="year" type="pint" indexed="true" stored="true" ↩

       multiValued="false" />

<field name="month" type="string" indexed="true" stored="true" ↩

       multiValued="false" />

<field name="day" type="pint" indexed="true" stored="true" ↩
      multiValued="false" />

<field name="day_of_week" type="string" indexed="true" stored="true" ↩

       multiValued="false" />


Line 1:

This defines the field solr_date to the type type, which is then matched to the fieldType solr.DatePointField - Panl can configure this field as a DATE range facet field.

Line 2:

This is the textual representation of the date, used to be displayed in the field sets that get returned

Line 3-6:

Instead of using the date field, additional fields are defined that use the date to enable faceting on the year (as an Integer), the month (as a String - e.g. January, February, etc.), the date (as an Integer), and the day_of_week (as a String - e.g. Monday, Tuesday, etc.)  This allows the user to facet on the year, or day, or month, or day of week, whilst still allowing a DATE range.  As an example:

http://localhost:8181/panl-results-viewer/simple-date/default/next+12+months/S/ 

Will show the following page.

IMPORTANT: The simple-date sample dataset and configuration was not set up in the instructions in the book, to see this example you will need to create the Solr collection and insert the data - see the /sample/solr/simple-date/ and /sample/panl/simple-date/ directories from the release package.  Brief instructions are included in the Additional Data Chapter.



Image: The DATE range of 'next 12 months' with the returned facets

Additional Properties

  • panl.date.<lpse_code>.previous=<string>

    This property sets the string that will be used to indicate that the DATE Range is for a previous length of time.
  • panl.date.<lpse_code>.next=<string>

    This property sets the string that will be used to indicate that the DATE Range is for a previous length of time.
  • panl.date.<lpse_code>.years=<string>

    This property sets the string that will be used as the range should be for years.
  • panl.date.<lpse_code>.months=<string>

    This property sets the string that will be used as the range should be for months.
  • panl.date.<lpse_code>.days=<string>

    This property sets the string that will be used as the range should be for days.
  • panl.date.<lpse_code>.hours=<string>

    This property sets the string that will be used as the range should be for hours.

IMPORTANT: You __MUST__ set __ALL__ of the above to enable the DATE Range facet.  Whether you choose to allow users to be able to facet on either one or both is up to you.

Example

The simple-date.panl.properties defines the solr_date Solr field as a DATE Range facet, the definition is below:

01

02

03

04

05

06

07

08

09

10

# <field "indexed"="true" "stored"="true" "name"="solr_date" "type"="pdate" ↩

         "multiValued"="false" />

panl.facet.S=solr_date

panl.name.S=Solr Date

panl.type.S=solr.DatePointField

panl.date.S.previous=previous

panl.date.S.next=next

panl.date.S.years=\ years

panl.date.S.months=\ months

panl.date.S.days=\ days

panl.date.S.hours=\ hours


The above configuration will allow the generation of URL paths such as:

  • next 30 days
    /next+30+days/S/
  • previous 10 hours
    /previous+10+hours/S/

Or any combination of previous/next with a value, followed by any one of years/months/days/hours

The format for a DATE Range facet is

<range_identifier><value><range_type>

IMPORTANT: If the range identifier or range type does not __EXACTLY__ match the configured values, then the value will be ignored and not passed through the Solr server.

Decoding the URL

The URL decoding is straightforward.  Panl will know from the LPSE code that this is a DATE Range facet and will then parse the URL path value.  Should the parsed value be valid (i.e. the range identifier and type are correct), then this will then be passed through to the Solr search server.

/

previous+

10

+hours

/

S

/

This is range identifier

This is value

This is the range type

The LPSE code

URL Path Value

A search on the simple date collection for the next 2 years

http://localhost:8181/panl-results-viewer/simple-date/firstfive/next+2+years/S/ 

Will pass through to Solr the following query:

q=*:*&q.op=OR&facet.limit=100&fl=solr_date,text_date,decade,year,month&facet.mincount=1&ro
ws=
10&facet.field=day&facet.field=month&facet.field=day_of_week&facet.field=decade&facet.f
ield=text&facet=true&fq=solr_date:[NOW+TO+NOW%2B2YEARS]&start=0

In the above, the Solr range query is fq=solr_date:[NOW+TO+NOW%2B2YEARS] which, when URL decoded is fq=solr_date:[NOW+TO+NOW+2YEARS].

Some Notes

About Value Replacements

This section covers prefixes, suffixes, infixes, and Boolean true/false value replacements.

Prefixes and suffixes can be added to any Panl facet definition, irrespective of the field type.  These will be transparently added and removed from the URL path when Panl processes it. Prefixes and suffixes have no effect on Panl field definitions.

IMPORTANT: The decoded URL path part __MUST__ exactly match the defined prefix/suffix/infix value.  If it is not an exact match, then Panl will not pass the query value through to Solr.

Defining a Prefix

panl.prefix.<lpse_code>=<your_prefix_here>

Prefixes are available on all facets, but are not used on fields.

In the case of a RANGE facet, these prefixes are still used if a singular value of this facet is selected - remember, Panl fields that are defined as RANGE facets return both range values and individual values.

If a range is selected, then this value is not used, instead the range prefixes and suffixes are used.

Defining a Suffix

panl.suffix.<lpse_code>=<your_suffix_here>

Suffixes are available on all facets, but are not used on fields.

In the case of a RANGE facet, these suffixes are still used if a singular value of this facet is selected - remember, Panl fields that are defined as RANGE facets return both range values and individual values.

If a range is selected, then this value is not used, instead the range prefixes and suffixes are used.

Defining an Infix

An infix is only available on RANGE facets and is set by the property

panl.range.infix.<lpse_code>=<your_infix_here>

If this property is not set, then the tilde character '~' will be used as a default.

Defining Boolean true/false replacement

These are only enabled if the Solr field type is solr.BoolField and will be ignored otherwise, example properties

panl.bool.<lpse_code>.true=able to be disassembled

If the boolean field value is true, then the above property will be used in the URL path part.  Remember that a prefix and suffix may still be applicable on the boolean value, which will be prepended and/or appended to the above value.

panl.bool.<lpse_code>.false=cannot be disassembled

If the boolean field value is false, then the above property will be used in the URL path part. Remember that a prefix and suffix may still be applicable on the boolean value, which will be prepended and/or appended to the above value.

IMPORTANT: If you wish to have whitespace before the suffix (or prefix, although unlikely) you must backslash encode the whitespace. For example, the brand Solr field has both a prefix and suffix, with the suffix requiring a 'space' between the value and the text

panl.facet.b=brand

panl.name.b=Brand

panl.type.b=solr.StrField

panl.prefix.b=Manufactured by

panl.suffix.b=\ Company

Note the \ Company value above for the panl.suffix.b property



On Field Validations

Field validations in Panl only support the integer and floating point types in Solr. The validations that occur within Panl simply strips out any non-matching characters, ensures that it is in the correct format for the field type and then passes it to the underlying Solr server.

The second type of validation is ensuring that the prefix/suffix and boolean value replacements are an exact match.  If there is no match, the passed in request part is discarded and not passed through to the Solr search engine.

About Hierarchical Facets

In the book store example, the first_published_year (LPSE code 'f') Solr field will only appear if the decade_published (LPSE code 'D') Solr field has been selected.  The property set on the first published Solr field:

panl.when.f=D

Shown below are the facets available with an empty search (left).  Once a value for the 'Decade Published' facet has been selected. The 'First Year Published' facet is shown (right).

 

Image:  The Panl Results Viewer web app showing the hierarchical facet of 'First Published Year' only appearing after the 'Decade' facet has been selected.  

Notes: __ANY__ Panl configured facet can have a hierarchy applied to it and the hierarchy can depend on any other facet, including Panl parameters (e.g. page, query string, number of pages, etc).


About Sorting Facets

By default, Solr will return facets ordered by the number of documents which contain the specific facet.  In the below image (taken from the Book Store collection), the books in the dataset with authors having a surname starting with C is 11, D is 3.

Note: This is __NOT__ the same as the sort fields defined by the property panl.sort.fields, which will sort the returned documents, this is for sorting the returned facets.

For some facets you may wish to order this in a more logical way for the end user - i.e. in alphabetical order.  To do this, you can set the panl.facetsort.<lpse_code> property to index, rather than the default of count (if the property is not included).




Image:  The Panl Results Viewer web app showing the Authors A-Z facet ordered by 'count' which is the default.  

By setting the  panl.facetsort.<lpse_code> property to index the facet results will be sorted by their value, not their count.



Image:  The Panl Results Viewer web app showing the Authors A-Z facet ordered by 'index' or the value of the facet.  


In the above image, the facet results are the same, however the resulting list of facets are now in alphabetical order - the books in the dataset with Authors having a surname starting with
C is 11, D is 3 as was expected.

Notes: The facet sorting option can be applied to __ANY__ Panl configured facet.

~ ~ ~ * ~ ~ ~