Field sets are the groups of data fields that you want to expose for each item when you request them through the item search API. Any time you see product data (eg on a product detail page, product list page, during the checkout, etc) then the likelihood is you’ve used the item search API — as well as a field set that defines what data should be returned on those requests.
Facets are used to filter search results based on the values of those data fields. For example, all or some of your items could have colors and a shopper may want to see results for items that have a particular color.
The item data you use in your field sets and facets is highly customizable — static or dynamic, standard or custom, etc — so it’s important to understand how the values for those fields are derived and whether they are necessary. Generally speaking, the more fields you have the longer it will take to return results; the more computationally expensive those fields are, the longer it will take.
Fields and Field Sets
If you make a request to the item search API without specifying any fields or field sets then you’ll just get back an array of objects where each item just lists its internal ID, so it’s important to specify the fields you need for what you’re doing. For example, when displaying items in a list, you’ll probably want fewer item fields than when you show an individual item on a detail page.
While you can specify individual fields to include on each request to the API, it’s preferable to define sets of fields ahead of time so that the data model is standardized across all pages of a particular type.
Field sets are set up per domain on the web site setup record. There are a number of defaults included with your site’s initial setup (usually determined by a script). However, as your site evolves, it is normal to make modifications: add new field sets or add new fields to existing field sets.
Performance Costs of Individual Fields
The principle problem we say is performance related — each extra field you request comes with a cost, and some fields’ costs are higher than others. Some fields, such as a name or description field, are relatively cheap as they are static; others, such as those related to live stock information, can be quite expensive.
As a developer you should regularly take stock of the changes you have made to your field sets and only include the fields you need.
The quantityavailable field is a very useful field because it gives live stock information, which is useful on product list and product detail pages as we (and our shopper!) want to know whether how many of the particular item is in stock. If an item isn’t in stock, then they might not want to order it (and we might want to tell them this before they order). If it is, we might to check if it’s low and perhaps show a promotional banner encouraging them to order the item before it sells out!
Therefore, it’s an intensive field to generate data for, but it’s worth doing in this scenario.
But what about when we request item data on any existing order, which the shopper is reviewing in their purchase history? In this scenario, it is not very useful for them know how many more they could order. Furthermore, in the context of an existing order, and including it in the field set for this scenario is a waste of computational (and shopper) time.
Therefore, when including a field, consider whether it needs to be there and whether it is worth the performance hit.
Examples of Expensive Fields
The below table lists some expensive fields and their intended use, along with field sets that they shouldn’t be added to and why. Note that if a field set is not listed, it doesn’t mean that it’s automatically OK to use them — the ones listed are places where one might commonly think to use the field (but probably shouldn’t).
|Field||Intended Usage||Recommended Field Sets to Avoid||Explanation|
|correlateditems_detail, relateditems_detail||Generating a list of items (and their details) associated with a particular item||details, order, search, typeahead||They work best when you are specifying one or a small number of items for a particular purposes such as a merchandising zone at the bottom of a product detail page|
|matrixchilditems_detail||Generating a list of items that have a child relationship to the specified product||order*, search, typeahead||It's usually unnecessary to generate the details of matrix children when you are viewing a list of products (you may use it in the order field set but note that orders with many lines may be particularly slow)|
|itemoptions_detail||Generating a list of item options (all item options, and their values) for a particular item||search*||It is included by default in a number of field sets, including the search field set, but depending on your site's performance you may want to remove it|
|quantityavailable||The total available of a particular item||order||Unnecessary as it provides detail on the live stock status when a shopper is not likely to need that information|
|quantityavailable_detail, quantitybackordered_detail, quantitycommitted_detail, quantityonhand_detail, quantityonorder_detail||Breakdowns of stock quantities in context of its status (typically associated with multi-location inventories)||order, search, typeahead||Stock fields are very expensive, and for most purposes you can use cheaper fields, such as isinstock and ispurchasable if you require a boolean value|
The fields marked with an asterisk (*) are contextual recommendations.
The common theme in this table is to do with fields that provide details. When you’re adding fields to a field set it can be deceiving because these fields occupy one line just like all the others, however, in reality, they actually provide objects (usually large ones) of data that can be particular expensive to derive.
Defining Unique Field Sets
If you look at the field sets pre-defined for your site then you’ll note that we have different ones for different purposes. The reason for this is alluded to above: you don’t want to have unnecessary expensive fields in field sets that don’t need them. However, a crucial thing to keep in mind is that, just like a lot of other performance problems, loads of small performance issues can build up to a big one.
Therefore, while you may not think that any one field is problematic for your site’s performance, know that there are certainly multiplicative forces that can act on that.
If a response contains an unnecessary field then the time it takes to generate data for that field could be multiplied up to 100 times if, for example, you requested 100 items on a product list page.
If you’ve got matrix child items, then this could be further multiplied, depending on the number of matrix combinations your items have.
Therefore, you should think each and every field set you use. When prototyping a new customization, it can be easy to rely on an existing field set for your items’ data. However, unless you need the data to be exactly the same, you may want to create a brand new field set.
The above advice about item fields and field sets applies in a general sense to facet fields. However, there are some additional considerations when you think about adding a new facet, such as:
- How likely it is that a shopper may actually use it (ie is it a useful filter?)
- How many values will the facet return?
- How many items will each of those facet values return?
These questions are also usability questions. A facet with a lot of unique options (ie that only apply to one product) may not be particular useful to a shopper looking to narrow down results. Similarly, a search that returns a large number of facets may overwhelm the shopper. A combination of both might not only overwhelm the customer must also the service that provides the results.
We recommend keeping facets to a maximum of 40. This is not a hard limit but our investigations with live sites indicate that once you approach this number, performance degradation is particularly noticeable.
As for facet values, we do not recommend exceeding 1,000. Also, you must keep each facet value’s name under 200 characters.
include=facets and facet.exclude Parameters
Only include the facets when you need them. In all standard parts of the site source code and configuration, we have set these parameters appropriately, but you need to keep this in mind when you’re performing your own searches.
When making a request to the item search API, omitting
include=facets from the request URL will ensure that the facets are not generated and returned, which will improve performance. You generally only need this information on product list pages.
If you do need facets but you know you can exclude specific ones, then using
facet.exclude in your request URL can remove that facet from the results.
Prevent a Facet from Rendering in Search Results
If you have set up a facet on your site, but you don’t want it to be an option that shoppers can select to filter search results with, you can exclude it from rendering.
The best way to do this is to use a filter we have set up in facets_facet_browse.tpl. In it is a placeholder where the Facets.FacetedNavigation child view will be rendered, which should have a
data-exclude-facets attribute on it. Add your facet to this attribute’s value.
<div data-view="Facets.FacetedNavigation" data-exclude-facets="commercecategoryname,category,myfacet,myotherfacet"></div>