Skip to main content

Facet Configuration

In the QSC Admin it is possible to configure different facets in the facet tab. facet-configuration.png

  • text: the text that can be displayed in the frontend

  • id: a unique id to identify the facet

  • fieldName: the fieldName of the index to query facet values

  • type: defines the type of the facet

    • slider: a slider for numeric values
    • select: string facet where just one value can be selected in the frontend
    • multiSelect: string facet where multiple values can be selected, the values are combined by the defined operator
    • humanDate: a facet to display human date values
    • dateHistogram: a facet to display date values as a histogram
    • histogram: a facet to display numeric values as a histogram
  • diesplayType: defines the type that is returned in the response of the API

    • slider: a slider for numeric values
    • select: string facet where just one value can be selected in the frontend
    • multiSelect: string facet where multiple values can be selected, the values are combined by the defined operator
    • humanDate: a facet to display human date values
    • custom values for individual implementations in the frontend
    • dateHistogram: a facet to display date values as a histogram
    • histogram: a facet to display numeric values as a histogram
  • operator: the operator for filtering the facet (OR AND)

  • sort: sorting the facet values

    • _count desc: sort by count descending
    • _count asc: sort by count ascending
    • _key desc: sort by the name of the facet value descending
    • _key asc: sort by the name of the facet value ascending
  • count: the count of facet values that should be displayed

  • display:

    • true: the facet is displayed in the response
    • false: the facet is not displayed in the response
    • default: true
    • in the GET API a facet can be forced to display with the parameter result.displayFacets=timestamp
    • in der POST API use {"result" : {"facet" : {"facets" : {"timestamp" : {} }}}}
    • for details see the search-api-integration guide

Load more facets

img.png

img.png

To globally load more facet values the control parameter loadMoreFacets must be set. All facets that are tagged by loadMoreFacetsAndSortByName return all facet values and are sorted by the name of the facet value.

Maximum of returned values is 10.000

GET Parameter

ctrl=loadMoreFacets

Configuration

load all facet values and sort the facet values by name

  • tag: loadMoreFacetsAndSortByName

Preselect facet values

For some facets it is useful to preselect a value or multiple values. Preselected values are configured in the facet configurations selectedValues The selected value is applied as a search filter for a request. In the response, this facet value is flagged as select. If the preselected value don't exists in the data, no results are returned.

{
"facetConfig": {
"facetConfigs": [
...
]
}
}
{
"facetConfig": {
"facetConfigs": [
{
"id": "color",
"name": "Farbe",
"type": "multiSelect",
"displayType": "multiSelect",
"fieldName": "color",
"operator": "OR",
"displayCount": 10,
"sort": "_key asc",
"selectedValues" : [
{
"value" : "red"
}
]
}
]
}
}

Open Issues

  • when the user explicitly remove the preselected filter, the preselected value must not be applied as a filter

To solve this issue there are multiple approaches:

  • 1.) values == null
{
"searchFilters": [
{
"id": "color",
"values": null
}
]
}
  • 2.) values: [] empty array
{
"searchFilters": [
{
"id": "color",
"values": [
]
}
]
}
  • 3.) local ctrl parameter for the filter
{
"searchFilters": [
{
"id": "color",
"ctrl" : [
"changed"
],
"values": [
]
}
]
}
  • advantage:

    • the changed flag is just applied for this specific filter
    • preselected values of other facets must not be set in the request
  • 4.) global ctrl parameter

  • advantage:

    • easy to implement
  • disadvantage

    • the frontend must set all preselected filters in the request

Defined Range Facet

For the API user this facet is identical to a string facet. The response is returned like a string facet. To Filter for a facet value just add the filter like in a string facet.

The facets can be configured directly in the search configuration or in the Facet configuration

  • search -> Facets
  • facet
{
"facetConfig": {
"facetConfigs": [
...
]
}
}

Properties

  • type: definedRange
  • minCount: - only facet values with the defined minimumCount are returned
    • default: 0 - all facet values are returned ( minCount >=0 )
  • sort: the sort parameter is ignored. The values are returned in the specified order of the values

numeric values

{
"facetConfig": {
"facetConfigs": [
{
"id": "stock",
"name": "stock",
"type": "definedRange",
"fieldName": "stock",
"operator": "OR",
"displayCount": 50,
"sort": "_count desc",
"parameters" :{
"minCount" : 1,
},
"values": [
{
"value": "not available",
"max": 1
},
{
"value": "limited availability",
"min": 1,
"max": 5
},
{
"value": "available",
"min": 5
}
],
"selectedValues": []
}
]
}
}
{
"result": {
"products": {
"facets": [
{
"name": "stock",
"id": "stock",
"type": "definedRange",
"filterName": "f.stock",
"count": 3,
"resultCount": 36,
"values": [
{
"value": "not available",
"count": 33,
"filter": "f.stock=not+available",
"position": 0
},
{
"value": "limited availability",
"count": 0,
"filter": "f.stock=limited+availability",
"position": 1
},
{
"value": "available",
"count": 3,
"filter": "f.stock=available",
"position": 2
}
]
}
]
}
}
}

date values

defined-range-facet-example.png

{
"facetConfig": {
"facetConfigs": [
{
"id": "creationDate",
"name": "Zeitraum",
"type": "definedRange",
"displayType": "multiSelect",
"fieldName": "creationDate",
"operator": "OR",
"displayCount": 50,
"sort": "_count desc",
"text": "Zeitraum",
"values": [
{
"value": "Letzte 3 Tage",
"min": "now-3d/d",
"max": "now+1d/d"
},
{
"value": "Gestern",
"min": "now-1d/d",
"max": "now/d"
},
{
"value": "Heute",
"min": "now/d",
"max": "now+1d/d"
},
{
"value": "diese Woche",
"min": "now/w",
"max": "now+1w/w"
},
{
"value": "letzte Woche",
"min": "now-1w/w",
"max": "now/w"
},
{
"value": "dieser Monat",
"min": "now/M",
"max": "now+1M/M"
},
{
"value": "letzter Monat",
"min": "now-1M/M",
"max": "now/M"
}
],
"selectedValues": []
}
]
}
}
{
"result": {
"products": {
"facets": [
{
"name": "Zeitraum",
"id": "creationDate",
"type": "multiSelect",
"filterName": "f.creationDate",
"count": 7,
"resultCount": 0,
"selected": true,
"values": [
{
"value": "Letzte 3 Tage",
"count": 0,
"filter": "f.creationDate=Letzte+3+Tage",
"position": 0
},
{
"value": "Gestern",
"count": 0,
"filter": "f.creationDate=Gestern",
"position": 1
},
{
"value": "Heute",
"count": 0,
"filter": "f.creationDate=Heute",
"position": 2
},
{
"value": "diese Woche",
"count": 0,
"filter": "f.creationDate=diese+Woche",
"position": 3
},
{
"value": "letzte Woche",
"count": 0,
"filter": "f.creationDate=letzte+Woche",
"position": 4
},
{
"value": "dieser Monat",
"count": 0,
"filter": "f.creationDate=dieser+Monat",
"position": 5
},
{
"value": "letzter Monat",
"count": 0,
"filter": "f.creationDate=letzter+Monat",
"selected": true,
"position": 6
}
]
}
]
}
}
}

min value is included max value is excluded

https://de.wikipedia.org/wiki/Sonnenfinsternis_vom_25._Oktober_2022

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math

TODO:

  • time zones

Slider

Config

{
"facetConfig": {
"facetConfigs": [
{
"id": "price",
"name": "price",
"type": "slider",
"displayType": "slider",
"fieldName": "price",
"operator": "AND",
"displayCount": 5,
"sort": "_count desc"
}
]
}
}

GET API

  • f.price.range=25,67

POST API

{
"searchFilters": [
{
"id": "price",
"filterType": "range",
"minValue": 0.99,
"maxValue": 11.11
}
]
}

Response

{
"result": {
"trendware": {
"facets": [
{
"name": "price",
"id": "price",
"type": "slider",
"filterName": "f.price",
"count": 1004,
"selected": true,
"minValue": 25,
"maxValue": 67,
"minRange": 19.99,
"maxRange": 68.99
}
]
}
}
}

Human Date Facet

!Depricated: use the defined range facet instead

  • a human date facet is just configurable in the raw tab
  • TODO: implement a ui for configuration
  • the fieldName must be from type date and there must be a keyword field from type date in the index configuration
{
"id": "timestamp",
"name": "timestamp",
"type": "humanDate",
"fieldName": "timestamp",
"operator": "OR",
"displayCount": 50,
"sort": "_count desc",
"values": [
{
"value": "letzten 7 Tage"
},
{
"value": "letzten 30 Tage"
},
{
"value": "letzten 6 Monate"
},
{
"value": "2022"
},
{
"value": "2021"
}
]
}

Search Facet

The search facet returns a facet entry of type and displayType search In this case the frontend can render a search input box.

{
"facetConfig": {
"facetConfigs": [
{
"id": "searchBox",
"name": "Suche",
"type": "search",
"displayType": "search",
"fieldName": "searchBox",
"operator": "AND",
"displayCount": 5,
"sort": "_count desc"
}
]
}
}

Date Histogram Facet

  • TODO

Color Picker Facet

{
"facetConfig": {
"facetConfigs": [
{
"id": "color",
"name": "Farbe",
"type": "multiselect",
"displayType": "colorPicker",
"fieldName": "color",
"operator": "OR",
"displayCount": 50,
"parameters": {
"config": {
"colorMappings": {
"grün": "#8aa281",
"blau": "#364d70",
"rot": "#c4393a"
}
}
}
}
]
}
}

Histogram Facet

{
"facetConfig": {
"facetConfigs": [
{
"id": "price",
"name": "price",
"type": "histogram",
"displayType": "histogram",
"fieldName": "price",
"parameters": {
"interval": 2.5,
"min_doc_count": 1
}
}
]
}
}
  • interval:
  • min_doc_count:

Response:

{
"result": {
"products": {
"facets": [
{
"name": "price",
"id": "price",
"type": "histogram",
"filterName": "f.price",
"count": 50,
"resultCount": 1004,
"values": [
{
"value": 19,
"count": 20,
"filter": "f.price=19.0"
},
{
"value": 20,
"count": 20,
"filter": "f.price=20.0"
},
{
"value": 21,
"count": 20,
"filter": "f.price=21.0"
}

]
}
]
}
}
}

Search Facet

Configuration:

{
"facetConfig": {
"facetConfigs": [
{
"id": "q",
"name": "Suche",
"type": "search",
"displayType": "search"
}
]
}
}

Response:

{
"result": {
"trendware": {
"facets": [
{
"name": "Suche",
"id": "q",
"type": "search"
}
]
}
}
}

RangeInput Facet

Configuration:

{
"facetConfig": {
"facetConfigs": [
{
"id": "price",
"name": "Nam Preis in $",
"type": "rangeInput",
"displayType": "rangeInput",
"fieldName": "price",
"unit": "$"
}
]
}
}

Response:

{
"result": {
"trendware": {
"facets": [
{
"name": "Preis in $",
"id": "price",
"type": "rangeInput",
"unit" : "$"
}
]
}
}
}

DatePicker Facet

Configuration:

{
"facetConfig": {
"facetConfigs": [
{
"id": "created_at",
"name": "Erstellt am",
"type": "datePicker",
"displayType": "datePicker",
"fieldName": "created_at"
}
]
}
}

Response:

{
"result": {
"trendware": {
"facets": [
{
"name": "Erstellt am",
"id": "created_at",
"type": "datePicker"
}
]
}
}
}

Configuration:

{
"facetConfig": {
"facetConfigs": [
{
"id": "categories",
"name": "Kategorie",
"type": "navigation",
"displayType": "navigation",
"fieldName": "category",
"operator": "OR",
"displayCount": 100000,
"sort": "_count desc",
"parameters": {
"filterType": "value"
}
}
]
}
}
  • filterType: default -> id
    • value: the value is used for filtering
    • id: the id is used for filtering

Response:

{
"result": {
"trendware": {
"facets": [
{
"name": "Kategorie",
"id": "categories",
"type": "navigation",
"count": 11,
"values": [
{
"value": "Bekleidung",
"count": 504,
"filter": "Bekleidung",
"children": {
"values": [
{
"value": "Damen",
"count": 500,
"filter": "Damen",
"children": {
"values": [
{
"value": "Oberteile",
"count": 500,
"filter": "Oberteile",
"children": {
"values": []
}
}
]
}
},
{
"value": "Herren",
"count": 4,
"filter": "Herren",
"children": {
"values": [
{
"value": "Oberteile",
"count": 4,
"filter": "Oberteile",
"children": {
"values": []
}
}
]
}
}
]
}
}
]
}
]
}
}
}

CategorySelect Facet

The categorySelect facet returns a facet entry of type and displayType categorySelect

Configuration

  • TODO

In the blog post Category Select is a detailed description of this feature.

  • used in MagentaInfos for a special hub page

View Facet

With a facet of type view it is possible to create something like a view in a database. Values of other facets can be combined in this virtual facet. For each value a value and a source must be configured:

  • value - The value of the facet
  • source - a jexl condition describes from where the value is used
    • jexl:a.value('availability', 'available') - use the value available from the facet availability
    • jexl:a.firstValue('accountIds') - use the first from the facet accountIds
    • removeFacetById('availability') remove the facet availability

!Important

It is important to configure the facets in the correct order. A facet that used and removed must be configured at the end in the list of the configurations. A facet that is removed can not be used anymore after removal.

{
"facetConfig": {
"facetConfigs": [
{
"id": "fastFilter",
"name": "Schnellfilter",
"type": "view",
"displayType": "view",
"fieldName": "fastFilter",
"operator": "OR",
"displayCount": 50,
"sort": "_count desc",
"values": [
{
"value": "available",
"source": "jexl:a.value('availability', 'available').removeFacetById('availability')"
},
{
"value": "lastPurchased",
"source": "jexl:a.firstValue('accountIds').removeFacetById('accountIds')"
},
{
"value": "promotion",
"source": "jexl:a.value('bonus', 'promotion')"
},
{
"value": "topProduct",
"source": "jexl:a.value('bonus', 'topProduct')"
},
{
"value": "tecselectBonus",
"source": "jexl:a.value('bonus', 'tecselectBonus')"
},
{
"value": "abakusBonus",
"source": "jexl:a.value('bonus', 'abakusBonus')"
},
{
"value": "abakusPlusBonus",
"source": "jexl:a.value('bonus', 'abakusPlusBonus').removeFacetById('bonus')"
}
]
}
]
}
}

Used by Alexander Bürkle

Sorting Facet by defined values

Sometimes it is not useful to sort a facet based on the count or in alphanumerical order. If there is a defined set of values, the QSC can sort based on this defined values. A good example is the sorting based on T-Shirt Sizes, where the logical order is not based on count and alphanumerical order.

The values are defined in the facetConfig. For sort _values must be selected. The values property contains the values, that are sorted in the defined order in the list.

Example:

{
"facetConfig": {
"facetConfigs": [
{
"id": "tShirtSizes",
"name": "T-Shirt Sizes",
"type": "multiSelect",
"displayType": "multiSelect",
"fieldName": "tShirtSizes",
"sort": "_values",
"text": "T-Shirt Sizes",
"values": [
{
"value": "XS"
},
{
"value": "S"
},
{
"value": "M"
},
{
"value": "L"
},
{
"value": "XL"
},
{
"value": "XXL"
}
]
}
]
}
}

Used by MagentaInfos

Multidimensional Facets

TODO

  • Used in MagentaInfos for related documents feature.

SubFacet

With a SubFacet facet it is possible to combine the values of two different fields and bring them into a relation. Other terms for multidimensional facets include SubFacet, Hierarchical Facets, or Nested Facets

Examples:

  • make -> model for cars
- Cars
|- VW
| |- Up
| |- Golf
| |- Passat
|- Ford
| |- Mustang
| |- Focus
| |- Explorer
|- BMW
| |- 3 Series
| |- 5 Series
| |- X5
|- Mercedes-Benz
| |- C-Class
| |- E-Class
| |- GLE
|- Honda
|- Civic
|- Accord
|- CR-V
  • document type -> tags -> TODO prepare an example with the qsc documentation

For a hierarchical category navigation use the Abgrenzung Kategorie Baum -> Navigation

Configuration

With the field children a sub facet is configured. At the moment just one level is supported, because of a limitation in QSF. Contact us if you need more than one level.

{
"facetConfigs": [
{
"id": "supplierName",
"name": "Hersteller",
"type": "term",
"displayType": "multiSelect",
"fieldName": "supplierName",
"operator": "OR",
"displayCount": 10,
"sort": "_count desc",
"children": {
"id": "category",
"name": "Kategorie",
"type": "term",
"displayType": "multiSelect",
"fieldName": "category",
"operator": "OR",
"displayCount": 10,
"sort": "_count desc",
}
}
]
}

Response

  • in the response the sub facet returned for each value in the children field
  • to filter for a value in a subfacet the filter from the value must be used in the request
{
"result": {
"sub-facet": {
"total": 2892,
"facets": [
{
"name": "Hersteller",
"id": "supplierName",
"type": "term",
"filterName": "f.supplierName",
"count": 2,
"resultCount": 2879,
"values": [
{
"value": "WAGO",
"count": 2857,
"filter": "f.supplierName=WAGO",
"children": {
"name": "Kategorie",
"id": "category",
"type": "term",
"filterName": "f.category",
"count": 2,
"resultCount": 2361,
"values": [
{
"value": "Reihenklemmen",
"count": 2080,
"filter": "f.supplierName=WAGO&f.category=Reihenklemmen"
},
{
"value": "Kennzeichnungsmaterial",
"count": 281,
"filter": "f.supplierName=WAGO&f.category=Kennzeichnungsmaterial"
}
]
}
},
{
"value": "WAGO Kontakttechnik",
"count": 22,
"filter": "f.supplierName=WAGO+Kontakttechnik",
"children": {
"name": "Kategorie",
"id": "category",
"type": "term",
"filterName": "f.category",
"count": 2,
"resultCount": 12,
"values": [
{
"value": "Reihenklemmen",
"count": 9,
"filter": "f.supplierName=WAGO+Kontakttechnik&f.category=Reihenklemmen"
},
{
"value": "Industrielle Netzwerktechnik",
"count": 3,
"filter": "f.supplierName=WAGO+Kontakttechnik&f.category=Industrielle+Netzwerktechnik"
}
]
}
}
]
}
]
}
}
}