Faceted Navigation
Published by Crhistian Ramirez-Hernandez on July 30, 2024
Faceted navigation, also known as faceted search, is type of navigation that allows users to refine product search results by applying filters based on specific product attributes defined by the business, such as color or size.
Configuration
In OrderCloud facets must be derived from extended properties (xp); however, not all extended properties need to be facets. You can designate an extended property as a facet by creating a Product Facet. For example, creating the following product facet will instruct OrderCloud to index all products with xp.Facets.Color
as a facet.
1{2 "ID": "color",3 "Name": "Color",4 "XpPath": "Facets.Color",5 "ListOrder": 0,6 "MinCount": 1,7 "xp": {}8}
Property | Description |
---|---|
ID | A short unique ID for the product facet. If XpPath is not defined, then it will be assumed to be at |
Name | The display value for this facet |
XpPath | The path to the extended property, for nested values use dot notation. The value stored at this location should be a primitive (string, boolean, number), or an array of primitives if a product represents multiple facet values |
ListOrder | The order you want facets to appear in. Smaller numbers will appear first. |
MinCount | The minimum number of facet values required for the facet to appear. Set to 0 if you want to include zero-count facet values in list results. |
xp | Like any other resource can be used to enhance facets with additional functionality |
List response
Once configured, making API calls to either /me/products
or /products
will return a Meta.Facets
object which will be populated with facets relevant to the currently applied filters. By default facet values will be sorted by count (highest first).
1"Meta": {2 "Facets": [3 {4 "Name": "Color",5 "XpPath": "Facets.Color",6 "Values": [7 {8 "Value": "red",9 "Count": 310 },11 {12 "Value": "purple",13 "Count": 114 }15 ]16 }17 ],18 ...19 }20}
Apply facet filters
Facet filters function similarly to regular filters. You can apply them based on the facet values selected by the user.
For example, if a user selects the "purple" facet, the query would look like this:
1/me/products?xp.Facets.Color=purple
Understanding facet value count
Each facet value will show a count which represents the number of results that would be returned if that filter were applied to your current result set.
An important note about counts is that they are based on the following conventional assumptions:
When values of different facets are selected, those filters will be AND’d together, usually resulting in a smaller result set.
When different values of the same facet are selected, those filters will be OR’d together, usually resulting in a larger result set.
The above assumptions lead to three implications:
Facet counts consider all current filters except those on the same facet. For example, if you filter shirts by color=red, the size counts will only show red shirts in each size. Counts for other colors, like blue and green, remain unchanged (otherwise, they’d presumably all be zero).
Counts don't always reflect the exact size of the new result set. For example, assume a result set includes 20 red shirts and 15 blue shirts. Selecting red (20) returns 20 results. Adding blue (15) gives 35 results. This is normal behavior for faceted navigation and has been shown to be intuitive for users.
In order for counts to be reflected accurately, your filtering logic should match the conventions above
Product with multiple facet values for a single facet
Sometimes, a single product can be represented by multiple facet values. For example, consider the color attribute. For a single color, this is straightforward:
1{2 "ID": "tennis-shoes",3 "Name": "Tennis shoes",4 "Xp": {5 "Color": "red"6 }7}
However, if a product has multiple colors, such as being both red and white, you can use an array format. OrderCloud will correctly index and count the product for both the red and white facets:
1{2 "ID": "tennis-shoes",3 "Name": "Tennis shoes",4 "Xp": {5 "Color": [6 "red",7 "white"8 ]9 }10}
Facets for pricing
Faceting on price is a common requirement. In OrderCloud, a single product can have multiple prices, leading to a near-limitless combination of pricing configurations. Due to performance implications, faceting on individualized prices is not supported.
Instead, we recommend setting a common retail price on xp
1{2 "ID": "tennis-shoes",3 "Name": "Tennis shoes",4 "Xp": {5 "Price": "12.99"6 }7}
Using this retail price for filtering works well for B2C use cases. However, for B2B use cases, it's important to clarify to users that the faceted price represents a "retail" or "MSRP" price, which may differ from their actual negotiated price.
Best practices & Considerations
Be selective with facets – Not every extended property should be facetable. Consider that facets are user-facing elements. Some properties may not be appropriate to expose to end users or may not provide meaningful options. For example you may store routing codes on the product as xp.RoutingCodes=[123,456,789]
. These codes may be important for ensuring efficient and accurate movement through the supply chain, but are generally not relevant to end users for product selection or filtering purposes.
XP best practices apply – all of the best practices related to XP apply here since facets are built on top of XP. In particular be very careful about making sure the type used is consistent across all products. If your schema ever changes you’ll need to first change all your products and then manually kick off an index rebuild.
Facet values maximum display – Facet values are capped at 50 to ensure optimal performance. Even if more values are indexed, only the first 50 will be displayed. To manage this, it is recommended to apply filters to reduce the number of results and, consequently, the number of facet values. This approach not only enhances performance but also improves the user experience by preventing overwhelming lists of options.
Facet values case sensitivity – Facet values will appear in lowercase, even if the xp
value includes uppercase characters. If you need values displayed differently, apply a transformation using JavaScript or CSS on the frontend.
Use strings instead of decimals for accuracy – Decimal facets are not supported due to a limitation related to how floating point decimals are stored. In some scenarios, the stored value may differ from the value represented in the facet. To ensure accuracy, we recommend using strings instead of decimals for facet values.
Still have questions?
Ask in our Community Channel