Breadcrumbs

Offer search - Facets

Usage

A facet is linked to a field of the offer. With the facet values, the client will be able to filter the result of the initial query.

  • First step, facet request, ask for a facet on the targeted field using facets parameters. With the offers, a facet is returned with various values to help to filter the second request.

  • Second step, filter request, with the facet values, the client is able to filter the result of the initial query.

Check fields metadata to know which field can have a facet and can be filtered. The way the values are returned and, the way the client can filter depend on the distribution of the field.

Discrete distribution

Fields can have a discrete values distribution and can have a facet. For instance: merchantId, brandId, featureType, featureColor...

Check the fields with meta information as:

  • canFacet is true

  • distribution is discrete

First step, facet request:

Multiple facets with discrete distributions

  • Given  the input parameters are

name

value

filterBy

categoryId:100564913

facets

featureColor,featureType,flagGreenProduct

facetValuesOn

featureType:2

  • And  the Search result has facet count fields

field

value

count

feature_color

Blanc

112

feature_color

Rouge

65

feature_type

Athletisme

67

feature_type

Randonnee

12

greenproduct

false

50

greenproduct

true

55

  • When  the client perform a GET on /api/public/search/offers with the input parameters

  • Then  I get a response with status 200

  • And  the json response contains meta/facets with the following content

JSON
{
  "facets": {
    "flagGreenProduct": {
      "title": "Produit écologique",
      "canFilter": true,
      "filterKey": "flagGreenProduct",
      "distribution": "discrete",
      "index": -10,
      "values": [
        {
          "value": "false",
          "label": "false",
          "slugLabel": "false",
          "count": 50
        },
        {
          "value": "true",
          "label": "true",
          "slugLabel": "true",
          "count": 55
        }
      ]
    },
    "featureColor": {
      "title": "Couleur",
      "canFilter": true,
      "filterKey": "couleur",
      "distribution": "discrete",
      "index": 5,
      "values": [
        {
          "value": "blanc",
          "label": "Blanc",
          "slugLabel": "blanc",
          "count": 112
        },
        {
          "value": "rouge",
          "label": "Rouge",
          "slugLabel": "rouge",
          "count": 65
        }
      ]
    },
    "featureType": {
      "title": "Type",
      "canFilter": true,
      "filterKey": "type",
      "distribution": "discrete",
      "index": 4,
      "values": [
        {
          "value": "athletisme",
          "label": "Athlétisme",
          "slugLabel": "athletisme",
          "count": 67
        },
        {
          "value": "randonnee",
          "label": "Randonnée",
          "slugLabel": "randonnee",
          "count": 12
        }
      ]
    }
  }
}

To present the facet on the UI:

  • Use the field title to present the facet.

  • On the values, use the label and the count.

Second step, filter request:

On discrete distribution filter, the parameter template is filterBy=[filterKey]:[value]

  • [filterKey] is the field filterKey in the facet

    • for static fields such as merchantId, the filterKey is equal to the field value

    • for dynamic feature fields such as featureColor, the filterKey is a country specific value distinct from the field value

  • [value] is the field value in the values of the facet.

The difference between static and dynamic fields is explained in the model.

As for the previous example, apply the following filter: filterBy=couleur:blanc. You can also filter on several items with filterBy=couleur:blanc+rouge&filterBy=type:randonnee.

Multi-levels facets

Some facets (only for dynamic feature fields) can have multiple levels, displayed as a tree in the response.

Facet with multilevels glossary

  • Given  the input parameters are

name

value

country

fr

fieldAlias

minimal

filterBy

categoryId:100564913

facets

featureType

  • When  the client perform a GET on /api/public/search/offers with the input parameters

  • Then  I get a response with status 200

  • And  the json response contains meta/facets with the following content

JSON
{
  "facets": {
    "featureType": {
      "title": "Type",
      "canFilter": true,
      "filterKey": "type",
      "distribution": "discrete",
      "index": 1,
      "values": [
        {
          "value": "bottes",
          "label": "Bottes",
          "slugLabel": "bottes",
          "count": 67,
          "children": [
            {
              "value": "bottes-a-lacets",
              "label": "Bottes à lacets",
              "slugLabel": "bottes-a-lacets",
              "count": 12
            },
            {
              "value": "bottes-a-talon",
              "label": "Bottes à talon",
              "slugLabel": "bottes-a-talon",
              "count": 10
            }
          ]
        },
        {
          "value": "bottines-et-boots",
          "label": "Bottines et Boots",
          "slugLabel": "bottines-et-boots",
          "count": 53
        }
      ]
    }
  }
}

Continuous distribution

Fields can have a continuous values distribution and can have a facet. For instance: price, totalPrice, rebatePercentage...

Check the fields with meta information as:

  • canFacet is true

  • distribution is continuous

We can ask for facets with dynamic buckets: as the distribution of the values is continuous the ranges to put those values will depends on:

  • the smallest value of the available values

  • the largest value of the available values

  • the number of ranges requested

At the first call the available values are all offers in the system, once the client refine his search, the available values are reduced as well as the dynamic ranges.

For instance, on the field totalPrice if we have

  • the smallest value equals to 5

  • the largest value equals to 99

  • the number of ranges requested equals to 5

The offers will be put in the following buckets:

  • from 0 to 20

  • from 20 to 40

  • from 40 to 60

  • from 60 to 80

  • from 80 to 100

If the client apply filters on the field totalPrice to get only offers with totalPrice from 20 to 40, the offers will be put in the following buckets:

  • from 20 to 24

  • from 24 to 28

  • from 28 to 32

  • from 32 to 36

  • from 36 to 40

First step, facet request:

Facet on a continuous distribution - total price

  • Given  the input parameters are

name

value

filterBy

categoryId:100564913

facets

totalPrice

facetValuesOn

totalPrice:5

And  the Search returns following facet intervals for field totalprice

value

count

[0,100)

0

[100,200)

0

[200,500)

0

[500,1000)

17

[1000,2000)

568

[2000,5000)

1789

[5000,10000)

3590

[10000,20000)

1266

[20000,50000)

404

[50000,100000)

21

[100000,200000)

0

  • When  the client perform a GET on /api/public/search/offers with the input parameters

  • Then  I get a response with status 200

  • And  the json response contains meta/facets with the following content

JSON
{
  "facets": {
    "totalPrice": {
      "title": "Prix total",
      "canFilter": true,
      "filterKey": "totalPrice",
      "distribution": "continuous",
      "index": -20,
      "ranges": [
        {
          "from": 5,
          "to": 20,
          "count": 585
        },
        {
          "from": 20,
          "to": 100,
          "count": 5379
        },
        {
          "from": 100,
          "to": 500,
          "count": 1670
        },
        {
          "from": 500,
          "to": 1000,
          "count": 21
        }
      ]
    }
  }
}

To present the facet on the UI:

  • Use the field title to present the facet.

  • On the values, use the labeland the count.

Second step, filter request:

On continuous distribution filter, the parameter template are filterGreaterThan=[filterKey]:[value], filterGreaterThanEqual=[filterKey]:[value], filterLowerThan=[filterKey]:[value] and, filterLowerThanEqual=[filterKey]:[value]. On the first request, the values are put in buckets from a limit value to another limit value. To filter the request:

  • on the first bucket: use filterLowerThan=[filterKey]:[to]

  • on the buckets in the middle: use filterGreaterThanEqual=[filterKey]:[from] and filterLowerThan=[filterKey]:[to]

  • on the last bucket: use filterGreaterThan=[filterKey]:[from]

So with the previous example, apply the following filters:

  • on the first bucket: use filterLowerThan=totalPrice:20

  • on the second bucket: use filterGreaterThanEqual=totalPrice:20&filterLowerThan=totalPrice:40

  • on the third bucket: use filterGreaterThanEqual=totalPrice:40&filterLowerThan=totalPrice:60

  • on the fourth bucket: use filterGreaterThanEqual=totalPrice:60&filterLowerThan=totalPrice:80

  • on the last bucket: use filterGreaterThan=totalPrice:80