HomeDev guideRecipesAPI Reference
Dev guideUser GuidesLegal TermsNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev guide

Facets

Describes the facets field, part of the GraphQL API used for the Optimizely querying service, when retrieving faceted content in Optimizely solutions. It is a sibling field of items, which contain the matching hits.

The facets field enables the retrieval of facets. Facets are values in fields that can be used to navigate through the results by filtering. 

Fields used for faceting are suggested in the autocomplete of the GraphQL user interface. You can specify multiple fields and nested fields for faceting.

📘

Note

If only the facets should be returned, but there are no results, the limit parameter in the where field has to be set to 0. This will significantly improve the query times.

String and Bool fields

For each string or bool (filter) field, there are four optional parameters for each field:

  • orderType – By COUNT (default) or by VALUE. When sorting by VALUE, it is by lexicographical order, for instance, capital letters have a lower value than lowercase letters.
  • orderBy – Specifies ASC or DESC (default) order of the facets.
  • limit – Specifies up to 1000 facets to retrieve (default: 10).
  • filters – Specifies the facets that should be applied with the field. This can be a list of string values. This is used to support multi-select of facets, such as applying a facet as a filter to update the list of results while preserving the list of original facets but getting updated hit counts for the items and facets without filters. If the value of filters is an empty string "", then it is ignored.

📘

Note

There are cases where multiple facets within a field should be selectable and be applied (such as using checkboxes), where the original facets should persist so more facets can be enabled or disabled while only updating the result list and other facets.

How does a multi-select of facets work? The following example is by courtesy of Yonik Seely. Suppose you have the following fields with facets:

=== Size ===   === Color ===    === Brand ===
[Small] (7)    [ ] Red (2)      [ ] Nike (7)
[Medium] (5)   [ ] Blue (8)     [ ] Adidas (5)
[Large] (6)    [ ] Green (3)    [ ] Reebok (4)
               [ ] Black (5)    [ ] Under Armour (2)

If you select the facet Blue, then you get the updated view, where the other facets are updated, and the search results, but the original Color facets stay the same, so they can be turned on or off.

=== Size ===   === Color ===    === Brand ===
[Small] (3)    [ ] Red (2)      [ ] Nike (3)
[Medium] (2)   [x] Blue (8)     [ ] Adidas (2)
[Large] (3)    [ ] Green (3)    [ ] Reebok (2)
               [ ] Black (5)    [ ] Under Armour (1)

(Top Blue running shorts displayed here)

If you also select black, then you get this updated view:

=== Size ===   === Color ===    === Brand ===
[Small] (5)    [ ] Red (2)      [ ] Nike (5)
[Medium] (4)   [x] Blue (8)     [ ] Adidas (3)
[Large] (4)    [ ] Green (3)    [ ] Reebok (3)
               [x] Black (5)    [ ] Under Armour (2)

(Top Blue and Black running shorts displayed here)

The search results are expanded with the extra added filter in Color and the facet counts in the other fields.

The facets are projected by:

  • name – Shows the facet's name, which is the value that can be faceted on. 
  • count – Shows the facet count, which is the number of hits that would match the name.

Request with string example:

query MyQuery {
  StandardPage (locale: en, limit: 1) {
    items {
      RouteSegment
      Saved
    } 
    facets {
      RouteSegment (limit: 8, orderType: VALUE, orderBy: ASC) {
        name
        count
      }
    }
  }
}

The following code returns the facets as part of the facets projection:

"facets": {
    "RouteSegment": [
        {
            "name": "about-us",
            "count": 1
        },
        {
            "name": "become-a-reseller",
            "count": 1
        },
        {
            "name": "collaboration-made-simple",
            "count": 1
        },
        {
            "name": "contact-us",
            "count": 1
        },
        {
            "name": "download-whitepaper-alloy-track",
            "count": 1
        },
        {
            "name": "find-a-reseller",
            "count": 1
        },
        {
            "name": "management",
            "count": 1
        },
        {
            "name": "news-events",
            "count": 1
        }
    ]
}

Request example with multi-select of facets using filters, where only the items and counts of facets are updated while preserving the list of facets:

{
  Content(locale: en, limit: 1)  {
    items {
      _score
      Name
      ContentType
    }
    total
    facets {
      ContentType(filters: ["ImageFile"]) {
        name
        count
      }
    }
  }
}

The following code returns all original facets with original facet counts and the new updated result list that applies VideoFile to ContentType, resulting in 32 items:

{
  "data": {
    "Content": {
      "items": [
        {
          "_score": 0,
          "Name": "ToddSlayton.jpg",
          "ContentType": [
            "Image",
            "Media",
            "ImageFile",
            "Content"
          ]
        }
      ],
      "total": 32,
      "facets": {
        "ContentType": [
          {
            "count": 89,
            "name": "Content"
          },
          {
            "count": 34,
            "name": "Page"
          },
          {
            "count": 33,
            "name": "Media"
          },
          {
            "count": 32,
            "name": "Image"
          },
          {
            "count": 32,
            "name": "ImageFile"
          },
          {
            "count": 22,
            "name": "Block"
          },
          {
            "count": 12,
            "name": "StandardPage"
          },
          {
            "count": 8,
            "name": "PageListBlock"
          },
          {
            "count": 5,
            "name": "ContactPage"
          },
          {
            "count": 5,
            "name": "TeaserBlock"
          }
        ]
      }
    }
  },
  "extensions": {
    "correlationId": "f3c1dd78-5a01-4595-a3ef-a0065a1e0f28"
  }
}

An example of using filters for a multi-select request with Bool field example.

query MyQuery {
  AllPropertiesTestPage(locale: en) {
    facets {
      Boolfield(filters: "true") {
        name
        count
      }
    }
    items {
      Name
      Boolfield
    }
  }
}

The following code returns facets with a value equal to True.

📘

Note

Enter valid values for filters. There are only two possible values for Bool fields: true and false. If a string value other than these two possible values is inserted, the results are empty.

{
  "data": {
    "AllPropertiesTestPage": {
      "facets": {
        "Boolfield": [
          {
            "name": "true",
            "count": 1
          }
        ]
      },
      "items": [
        {
          "Boolfield": true
        }
      ]
    }
  }
}

Date fields

You can retrieve the facets of date fields as a histogram, where the latest 1,000 units of value are retrieved.

📘

Note

Date facets only return units with matching items. Only date facets with at least 1 matching item are shown to reduce the response size.

For each date field, there are two optional parameters:

  • value – The quantity for the unit. It can be an integer (default: 1)
  • unit – The unit of time. MINUTE, HOUR, or DAY (default).

An example request where you drop the items from the response and only project the facets:

query MyQuery {
  StandardPage (locale: en, limit: 0) {
    facets {
      Created (unit: DAY, value: 14) {
        name
        count
      }
    }
  }
}

The following code response does the bucketing of documents with the Created field by 14 days (bi-weekly):

"data": {
    "StandardPage": {
        "facets": {
            "Created": [
                {
                    "2012-08-02T00:00:00Z": 1
                },
                {
                    "2012-08-16T00:00:00Z": 2
                },
                {
                    "2012-08-30T00:00:00Z": 2
                },
                {
                    "2012-09-13T00:00:00Z": 2
                },
                {
                    "2012-09-27T00:00:00Z": 3
                }
            ]
        }
    }
}

Number fields

📘

Note

Facets for numbers can be used similarly to the String type. This is useful when the property is categorical data, for example, a shoe size. To get facets for the number type as categories, add any of the following categorical parameters: orderType, orderBy, limit, or filters.

By default, it will use the ranges parameter. If the ranges parameter is used with the categorical parameters, then the categorical facets have precedence.

For each number (filter) field, there is a ranges parameter and this parameter is an array of objects that has two optional parameters:

  • from – The minimum (lower bound) value in the range. This can be null.
  • to – The maximum (upper bound) value in the range. The upper bound value is treated as non-inclusive, so the to value needs to be higher than the from value to return results. This is indicated with the notation of the bucket name, like [10,100) (starting with a square bracket and ending with parenthesis). This can be null.

Request example:

query MyQuery {
  StartPage(locale: en) {
    items {
      Visitor
    }
    facets {
      Visitor(ranges: [{from: 10, to: 100}, {from: 1000}, {to: 100000}])
    }
  }
}

The following code returns the facets as part of the extensions section of the response:

"data": {
    "StandardPage": {
        "items": [...],
        "facets": {
            "Visitor": [
                {
                    "[,100000)": 1
                },
                {
                    "[10,100)": 1
                },
                {
                    "[1000,)": 0
                }
            ]
        }
    }
}

Combine facet types

In the facets projection, you can request a mixture of (multiple) different field types, letting you retrieve multiple facets of different fields in a single request.

Request example:

query MyQuery {
  Content(locale: en) {
    items {
      Name
      Changed
      ContentLink {
        Id
      }
    }
    facets {
      Changed(unit: DAY, value: 100) {
        name
        count
      }
      Name(limit: 10, orderBy: ASC, orderype: VALUE) {
        name
        count
      }
      ContentLink {
        Id(ranges: [{from: 10, to: 100}, {from: 1000}]) {
          name
          count
        }
      }
    }
  }
}