Product discovery
Composable Commerce's Product Projections Search endpoint is specifically designed for enhancing product discovery experiences like:
In this guide, we provide some hands-on examples demonstrating how to leverage the capabilities of the Product Projection Search API for these functionalities.
Be aware that due to our event-driven architecture, the changes to Products made with the Import API or the Products API could take up to 15 minutes to be reflected in the Product Projection Search API.
Prerequisites
Before proceeding to the following examples, make sure you have:
Activate Product Projection Search endpoint
You can activate the Product Projection Search endpoint either using the Change Product Search Indexing Enabled update action or in the Merchant Center from the Storefront search tab in Settings > Project settings.
Set relevant Product Attributes as searchable
To search Products by a particular Attribute, you need to set their AttributeDefinition as searchable. You can do it either by using the Change AttributeDefinition IsSearchable update action or utilizing the Merchant Center by navigating to Settings > Product types and attributes.
Product discovery is one of the topics to which you should pay most attention when designing your product data model.
When migrating to commercetools from your current system, you might tend to replicate your existing product data model. However, this often needs to be revised since it impacts your storefront performance, including product discovery. Be mindful that commercetools is the core commerce system in your composable landscape. Your product data model in commercetools should reflect what is necessary for your customers to find and purchase your products, with enough information to send downstream to process and fulfill orders.
We recommend carefully evaluating which Attributes you want to set as searchable. When making your decisions, be aware that:
- Fields that are indexed are quicker to search but may consume more storage resources.
- Making some Attributes as searchable and making others available only for retrieval can impact search capabilities and performance.
Before making an Attribute searchable, ask yourself if your storefront actually exposes the Attribute and if you need to filter, facet, or query the Attribute.
The name
, description
, slug
, and searchKeywords
of a Product and the related Product Variants' sku
fields are searchable by default. To make custom Attributes searchable, you must set them as searchable.
Full-text search
Full-text search lets you perform text-based queries on product data. It allows more complex search operations, like matching substrings, ranking results based on relevance, and performing fuzzy searches.
When you use full-text search, the Product Projection Search endpoint:
- Tokenizes the text fields into separate words or tokens.
- Normalizes the tokens by converting them to lowercase and possibly removing special characters.
- Matches the tokens against the indexed tokens in the product database.
- Ranks the results based on certain scoring algorithms that evaluate how the product data matches the query.
For example, the query /search?text.en=Shirts
will return all Products that contain the word Shirts in the English localized text.
Filtering by category
Filtering by category and by category subtrees lets you filter Products based on the Categories and child Categories they are assigned to.
The following diagram depicts an example of the relationship between Products and Categories.
Given this Products and Categories relationship, the following filters are available:
Filter Products belonging to Categories within the Tops Category tree.
For example, the queryfilter.query=categories.id:subtree("{tops-category-id}")
will return both the wool-knit-sweater and the graphic-t-shirt Products.Filter Products belonging to the T-Shirts Category.
For example, the queryfilter.query=categories.id:"{t-shirt-category-id}")
will return only the graphic-t-shirt Product.
This query looks for Products belonging to a particular Category. If the T-Shirts Category had child Categories, such as Crew Neck and V-Neck, the Products belonging to those child Categories would not be returned.Filter Products belonging both to T-Shirts and Sale Categories.
For example, the queryfilter.query=categories.id:"{t-shirt-category-id}"&filter.query=categories.id:"{sale-category-id}"
will return only the graphic-t-shirt Product.
Note that thefilter.query
is passed twice in this example. Passing multiplefilter
parameters combines the filters as anAND
operator.Filter Products belonging either to the Sweaters or Sale Categories.
For example, the queryfilter.query=categories.id:"{sweater-category-id}","{sale-category-id}"
will return both the wool-knit-sweater and the graphic-t-shirt Products.
Note that both Category IDs are passed to a singlefilter.query
parameter. Passing multiple values to a singlefilter
parameter works as anOR
operator.
Filtering by price
Price range matching
Range queries let you filter Products based on price ranges. Such a filter is widely used in commerce websites allowing customers to find products within their budget.
For example, the query filter.query=variants.scopedPrice.centAmount:range(0 to 10000)
will return all Products with at least one Product Variant that has a price between 0 and 100 (10000 cents).
Setting an upper or lower limit
You can use the greater than (>
) or the less than (<
) operators to filter Products above or below a certain price.
For example, the query filter.query=variants.scopedPrice.centAmount:>1000
will return all Product Variants with a price higher than 10 (1000 cents).
While the query filter.query=variants.scopedPrice.centAmount:<2000
will return all Product Variants with a price lower than 20 (2000 cents).
Faceted search
Faceted search lets you narrow down search results by applying multiple filters, called facets, based on the classification of products. You can use facets for Product Attributes such as size, color, brand, price range, and more. The Product Projections Search API supports the following types of facets:
When planning the use of faceted search, you should keep in mind that it can be resource-intensive, especially for large product catalogs. Using many facets in a single query can affect the performance of your commerce website.
TermFacets
TermFacets optimizes the shopping experience for your customers by allowing them to filter products based on shared characteristics, such as size or color.
TermFacets categorize and count Product Variants based on specific Attribute values.
For example, to display the number of products for each size and color in your product catalog, you can use the query facet=variants.attributes.size&facet=variants.attributes.color
that will return the following TermFacetResult.
...."facets": {"variants.attributes.size.key": {..."total": 25239,"other": 0,"terms": [{"term": "xxxl","count": 3224},{"term": "xs","count": 2504},{"term": "xxs","count": 1861}]},"variants.attributes.color.key": {..."terms": [{"term": "blue","count": 5624},{"term": "black","count": 3183},{"term": "grey","count": 3004}]}}
On your storefront, you would render the facet similar to the following image.
RangeFacets
RangeFacets improve the experience on your commerce website by allowing customers to filter products based on predefined value ranges, such as price.
For example, to display how many products you have in three price ranges, you can use the query variants.price.centAmount:range(0 to 5000),(5000 to 15000),(15000 to *)
.
On your storefront, you would render the facet similar to the following image.
FilteredFacets
FilteredFacets enhance the shopping experience by allowing your customers to narrow down search results based on specific characteristics of products, such as color, size, brand, or price. Unlike general facets that display all the available categories or attributes, FilteredFacets show only those that are relevant to the current search or selection.
For example, the query variants.attributes.size:"xxxl"
will return only Product Variants that have the size Attribute set to xxxl
.
On your storefront, you would render the facet similar to the following image.