Product Projection Search
Product projections can be retrieved using full-text search, filtering, and faceting functionality.
This endpoint provides high performance search queries over ProductProjections and is typically used to build Storefront Search functionalities that improve the discoverability of products for your customers. To optimize the usage of this endpoint for your project, check our performance tips.
Retrieving tailored product data is not supported by Product Projection Search. For such a scenario, use the Get ProductProjection in Store endpoints.
Currently there is no filtering, faceting or sorting support for Standalone Prices.
Please note that existing filters, faceting, and sorting options will still work, but will only consider Embedded Prices, therefore using these options on Products with Standalone
ProductPriceMode might yield inconsistent results.
Activation of the feature
The Product Projection Search API is not active for the Project by default. If the feature is deactivated for your Project, the Product Projection Search endpoint returns a SearchDeactivated error.
To activate the feature for your Project, please choose one of the following options:
- using the Merchant Center by navigating to Settings > Projects Settings > Storefront search.
- using the Change Product Search Indexing Enabled update action with
mode: ProductProjectionsSearch
on the Update Project endpoint.
{"action": "changeProductSearchIndexingEnabled","enabled": true,"mode": "ProductProjectionsSearch"}
As soon as the feature is activated for your Project, its Products get indexed, and the Product Projection Search API as well as the Product Suggestions API will become fully functional soon after.
Automatic deactivation
The Product Projection Search API and the Product Suggestions API will be deactivated for a Project automatically if there have been no calls to them for the duration of 30 consecutive days. The APIs can be reactivated again as described above.
Product Projection Search
Endpoint: /{projectKey}/product-projections/search
Method: GET
or POST
OAuth 2.0 Scopes: view_products:{projectKey}
, view_published_products:{projectKey}
Response Representation: PagedQueryResult with results
containing an array of ProductProjection
Query result and marked matching Variants
The query result contains the ProductProjections where at least one ProductVariant matches the search query. This means that variants can be part of the result where the search query does not match.
If markMatchingVariants
parameter is true
those ProductVariants that match the search query have the additional field isMatchingVariant
set to true
. For the other variants in the same product projection this field is set to false
.
If markMatchingVariants
parameter is false
the ProductVariants do not contain the field isMatchingVariant.
By default, the markMatchingVariants
parameter is set to false
, and needs to be explicitly set to true
if required.
Query parameters
text.{language}
- String - Optional
The text to analyze and search for, for example as supplied by a user through a search input field. Parameter must include the language in form of an IETF language tag. The content to search in, that means the full-text search, is only performed in the localized product content of the specified language.The API analyzes the product information as well as the search terms provided with
text
value according to natural language rules and decomposes the terms into its word parts. This could lead to search results that are not an exact match of the provided search terms. Non-alphanumeric characters contained in search terms are ignored. For instance, words separated by hyphens are not treated as one search term, but split into parts.fuzzy
- Boolean - Optional (defaults tofalse
)
Whether to apply fuzzy search on the text to analyze.fuzzyLevel
- Number - Optional (defaults to a value dynamically calculated by the API - see fuzzy search)
The fuzzy level desired iffuzzy
is enabled. This value can not be higher than the default one based on the length of the searched text.filter
- Filter - Optionalfilter.query
- Filter - Optionalfilter.facets
- Filter - Optionalfacet
- Facets - Optionalsort
- Sort - Optionallimit
- Number - Optionaloffset
- Number - Optionalstaged
- Boolean - Optional (defaults tofalse
)
Whether to search in the current or staged projections.
When using the OAuth 2.0 scopeview_published_products
, it is not permitted to usestaged
=true
.markMatchingVariants
- Boolean - Optional (defaults tofalse
)
Whether to mark product variants in the search result matching the criteria.priceCurrency
- String - Optional
The currency code compliant to ISO 4217. Enables price selection and Scoped Price Search.priceCountry
- String - Optional
A two-digit country code as per ISO 3166-1 alpha-2. Enables price selection and Scoped Price Search. Can only be used in conjunction with thepriceCurrency
parameter.priceCustomerGroup
- UUID - Optional
Enables price selection and Scoped Price Search. Can only be used in conjunction with thepriceCurrency
parameter.priceChannel
- UUID - Optional
Enables price selection and Scoped Price Search. Can only be used in conjunction with thepriceCurrency
parameter.storeProjection
- String - Optional
Key of an existing Store.
If the Store has defined some languages, distribution channels, supply channels, or countries, they are used to enable locale based projection, price based projection and inventory based projection respectively. If the Store has defined Product Selections or Product Tailoring, they have no effect on the results of this query.localeProjection
- String - Optional
IETF language tag.
Enables locale based projection.
To set more than one locale, use this query parameter multiple times.
The parameters are sent:
- with
GET
: as query parameters in the URI. - with
POST
: included in the body encoded inapplication/x-www-form-urlencoded
.
Example GET request
GET /{projectKey}/product-projections/search?staged=true&limit=10&text.en="simpsons"
Full-text search
The text.{language}
query parameter performs the full-text search on the ProductProjections.
Search results are based on the first 256
characters of the full-text search query parameter only. Everything beyond 256
characters will be ignored. You can continue to pass longer query parameters, the API call will still be successful.
Searchable fields
The Product Projections search conducts a full-text search over product projection's data. A product projection returns all variants a product has, and so product projection searches all variants of a product.
The following attribute types in a ProductProjection are searched by default. For localized properties, the product projection search only searches text matching the {language}
parameter in text.{language}
.
name
:name
is weighed more heavily than any other property.description
slug
sku
searchKeywords
The following ProductProjection properties are not indexed for full-text search:
metaKeywords
metaTitle
The following Product Attributes on a product variant are searched if the AttributeDefinition's isSearchable
is set to true
:
text
ltext
money
reference
- The
label
property of each AttributePlainEnumValue in anenum
orlenum
. - ReferenceType Product Attributes:
ReferenceType
attributes are not full-text searchable, but are available for filtering.
If no sort
parameter is given, the results are sorted by the relevance of the product to the search text passed.
Fuzzy search
When the fuzzy
query parameter is set to true
the search endpoint will also return ProductProjections that contain slight differences to the search text.
For example, when someone searches for 'whisky', the fuzzy search would also return products labelled with 'whiskey'.
To optimize the discovery of related terms, the level of fuzziness applied on the text is adapted dynamically depending on the length of the text to analyze.
The fuzziness level is quantified in terms of the Damerau-Levenshtein distance, this distance being the number of operations needed to transform one word into another.
The fuzzy level can be optionally set with the parameter fuzzyLevel
. However, the value may not exceed the default one selected dynamically based on the length of the searched text:
0
- for texts of one or two characters.1
- for texts of three, four or five characters.2
- for texts of more than five characters.
Filters
Search results can optionally be filtered and these filters can be applied for different scopes. These scopes are represented by different query parameters:
filter.query
This parameter applies a filter to the query results before facets have been calculated. Filters in this scope influence facet counts. If facets are not used, this scope should be preferred overfilter
.filter
This parameter applies a filter to the query results after facets have been calculated. Filters in this scope don't influence facet counts any more.filter.facets
This parameter applies a filter to all facets calculations (but not query results), except for those facets that operate on the exact same field as afilter
parameter. This behavior in combination with thefilter
scope enables multi-select faceting.
Passing multiple filter
parameters in one search request will combine them with an AND
operator.
The following example search request filters products of a certain category AND
of the color "black":
GET /{projectKey}/product-projections/search?filter=categories.id:"{id}"&filter=variants.attributes.color:"black"
Specifying multiple values in one filter
parameter, separated by a comma, will return products in which at least one of the specified values matches (OR
-operator).
The example search request below filters products of the color "black" OR
"grey":
GET /{projectKey}/product-projections/search?filter=variants.attributes.color:"black","grey"
Not all filters can be applied in all scopes, as is described below.
Filter by category
Keep only the products that belong to the specified Category:
categories.id:"{id}"
Keep products which are not assigned to any Category:
categories:missing
Note: empty Strings (""
) are not recognized as a missing value and are not caught by this filter.
Keep products which are assigned to at least one Category:
categories:exists
Category filters can be applied in the filter
, filter.query
and filter.facets
scopes.
Filter by category subtrees
Keep only the products that belong to the specified Category or any of its descendant categories:
categories.id: subtree("{id}")
To include products that belong to different branches of the category tree other subtree
functions can be added to the filter for which each specifies the Category of the other branch in the category tree:
categories.id: subtree("{id}"), subtree("{id2}")
The subtree
function can also be used in combination with several regular id filters:
categories.id: subtree("{id1}"), "{id2}", "{id3}"
Note, that specifying {id2} and {id3} is not necessary in case those categories are children of {id1}.
The subtree
function can also be applied in filter.facets
.
Filter by price
Only the first price will be used for filtering if a product variant has several Embedded Prices. If you want to use another product variant price (selected based on the price scope) then you should use Filter by Scoped Price instead.
Keep only the products which Embedded Price match the specified value or range (lower and upper bound included, use *
to ignore either the lower or the upper bound).
variants.price.centAmount:{amount}
variants.price.centAmount:range (* to {to})
variants.price.centAmount:range ({from} to {to}), ({from} to {to}), ...
Keep only products that contain a ProductVariant without any Embedded Price set:
variants.prices:missing
Note: empty Strings (""
) are not recognized as a missing value and are not caught by this filter.
Keep only products that contain a ProductVariant with at least one Embedded Price set:
variants.prices:exists
Price filters can be applied in the filter
, filter.query
and filter.facets
scopes.
Filter by price only works with Embedded Prices, there is currently no support for StandalonePrices.
Filter by Scoped Price
To be able to filter products by Scoped Price you must use Scoped Price Search.
ScopedPrice is a Price contained inside a ProductVariant selected based on the price scope like currency, country, Channel, and Customer Group.
This means that only those Product Variants with a Price matching all Price Selection Parameters contain the scopedPrice
field with the
ScopedPrice.
You can apply filters on the scopedPrice
field and its subfields like value
and currentValue
as described in this section.
Scoped Price filters can be applied as filter
, filter.query
and filter.facets
parameters.
Filter by Scoped Price only works with Embedded Prices, there is currently no support for StandalonePrices.
Filter by scopedPrice value
Filters, sorts, and facets products by the original product variant Embedded Price value. Here is an example:
variants.scopedPrice.value.centAmount:range (* to 1200)
Filter by scopedPrice currentValue
Filters, sorts, and facets products by either the original product variant Embedded Price value or a discounted value, if it's available. Here is an example:
variants.scopedPrice.currentValue.centAmount:1000
Filter by scopedPrice discounted value
Filters, sorts, and facets products by an Embedded Price discounted
value if it's available. Here is an example:
variants.scopedPrice.discounted.value.centAmount:range (* to 1200)
Filter by scopedPriceDiscounted
You can filter, facet, and sort by the Boolean
property variants.scopedPriceDiscounted
that would be true
if
a ProductDiscount had been applied on the Embedded Price.
Filter by SKU
Keep only the products with a ProductVariant matching the specified sku
:
variants.sku:{sku}
Keep only products that have a ProductVariant with no sku
set:
variants.sku:missing
Note: empty Strings (""
) are not recognized as a missing value and are not caught by this filter.
Keep only products that have a ProductVariant with a sku
set:
variants.sku:exists
SKU filters can be applied in the filter
as well as in the filter.query
scope.
Filter by Product Key
Keep only the product which matches the specified Product key
:
key:{key}
Keep only Products with no key
set:
key:missing
Note: empty Strings (""
) are not recognized as a missing value and are not caught by this filter.
Keep only Products with a key
set:
key:exists
Filter by ProductVariant Key
Keep only the products that have a ProductVariant which matches the specified key
:
variants.key:{key}
Keep only products that have a ProductVariant with no key
set:
variants.key:missing
Note: empty Strings (""
) are not recognized as a missing value and are not caught by this filter.
Keep only products that have a ProductVariant with a key
set:
variants.key:exists
Filter by productType
Keep only the product which matches the specified ProductType.
productType.id:{id}
ProductType filters can be applied in the filter
as well as in the filter.query
scope.
Filter by taxCategory
Keep only the products which match the specified TaxCategory.
taxCategory.id:{id}
Keep only products that do not belong to any TaxCategory:
taxCategory:missing
Note: empty Strings (""
) are not recognized as a missing value and are not caught by this filter.
Keep only products that have a TaxCategory set:
taxCategory:exists
TaxCategory filters can be applied in the filter
as well as in the filter.query
scope.
Filter by state
Keep only the products which match the specified State.
state.id:{id}
Keep only products that do not belong to any State:
state:missing
Note: empty Strings (""
) are not recognized as a missing value and are not caught by this filter.
Keep only products that have a State set:
state:exists
State filters can be applied in the filter
as well as in the filter.query
scope.
Filter by reviewRatingStatistics
Keep only the products which match the specified ReviewRatingStatistics.
reviewRatingStatistics.averageRating:{value}
reviewRatingStatistics.averageRating:range ({from} to {to}), ({from} to {to}), ...
reviewRatingStatistics.highestRating:{value}
reviewRatingStatistics.highestRating:range ({from} to {to}), ({from} to {to}), ...
reviewRatingStatistics.lowestRating:{value}
reviewRatingStatistics.lowestRating:range ({from} to {to}), ({from} to {to}), ...
Keep only products that have an average/highest/lowest rating matching the specified value or range (lower and upper bound included, use *
to ignore either the lower or the upper bound).
reviewRatingStatistics.count:{value}
reviewRatingStatistics.count:range ({from} to {to}), ({from} to {to}), ...
Keep only products that have a number of review ratings matching the specified value or range.
ReviewRatingStatistics filters can be applied in the filter
as well as in the filter.query
scope.
Filter by custom attribute values
To filter by a custom attribute value, the custom attribute must have the isSearchable
field set to true
in its AttributeDefinition.
Keep only the ProductVariants with the custom attribute matching the specified value or range (lower and upper bound included, use *
to ignore either the lower or the upper bound).
variants.attributes.{name}:"{value}"
variants.attributes.{name}:range ({from} to {to}), ({from} to {to}), ...
To keep the products that do not have a custom attribute set, use:
variants.attributes.{name}:missing
Note: empty Strings (""
) are not recognized as a missing value and are not caught by this filter.
To keep the products that contain a custom attribute, use:
variants.attributes.{name}:exists
If the custom attribute is of AttributeEnumType, the filter must be applied to the key
of the AttributePlainEnumValue:
variants.attributes.{myEnumName}.key:"{value}"
In case of AttributeMoneyType attributes, the filter must be applied to the Money object's centAmount
or currencyCode
property:
variants.attributes.{myMoneyAttribute}.centAmount:{value}
variants.attributes.{myMoneyAttribute}.centAmount:range ({from} to {to}), ({from} to {to}), ...
variants.attributes.{myMoneyAttribute}.currencyCode:"{value}"
In case of AttributeReferenceType attributes, the filter must be applied to the id
or the typeId
of the Reference:
variants.attributes.{myReferenceAttribute}.id:"{id}"
variants.attributes.{myReferenceAttribute}.typeId:"{typeId}"
In case of AttributeSetType attributes, the filter can be specified multiple times to search for a set that contains at least those values (AND
). Specifying multiple values, separated by a comma, will match if one of those values is present in the set (OR).
GET /{projectKey}/product-projections/search?filter=variants.attributes.colors:"green"&filter=variants.attributes.colors:"black","grey"
Custom attribute filters can applied in the filter
, filter.query
and filter.facets
scopes.
Filter by product variant availability
Keep only the ProductVariants with the availability matching the specified value or range (lower and upper bound included, use *
to ignore either the lower or the upper bound).
variants.availability.isOnStock:true
variants.availability.availableQuantity:range (1 to *)
For a specific supply Channel:
variants.availability.channels.<channel-id>.isOnStock:true
variants.availability.channels.<channel-id>.availableQuantity:range (1 to *)
For variants with ProductVariantAvailability isOnStock
equal to true
in at least one of the specified Channels:
variants.availability.isOnStockInChannels:"channel-id-1","channel-id-2","channel-id-3"
Filter by product searchKeywords
searchKeywords.{language}.text:"{value}"
Filter by datetime
Keep only the ProductVariants that were created or updated within the specified DateTime range.
Datetimes matching the lower and upper bound are included in the search result; use *
to ignore either the lower or the upper bound.
Filter by createdAt
createdAt:range ({from} to {to})
GET /{projectKey}/product-projections/search?filter.query=createdAt%3Arange%20(%222015-06-04T12%3A27%3A55.344Z%22%20to%20%222016-06-04T12%3A27%3A55.344Z%22)
Filter by lastModifiedAt
lastModifiedAt:range ({from} to {to})
Facets
Facets calculate statistical counts to aid in faceted navigation.
If one or more valid FacetExpressions are specified in the Product Projection Search the PagedQueryResult contains a facets
object additionally to the ProductProjections.
For each FacetExpression specified in the search request the facet
object contains a FacetResult.
By default FacetResults provide a count of ProductVariants. An additional count of Products can be requested via the extension counting products
.
Facet calculation is requested by providing FacetExpressions via the facet
query parameter.
GET /{projectKey}/product-projections/search?facet=variants.attributes.colors&facet=variants.attributes.size:"m"
This API endpoint supports three types of facets: TermFacets, RangeFacets, and FilteredFacets. Below each type is explained in more detail.
To facet by a custom attribute value, the custom attribute must have the isSearchable
field set to true
in its AttributeDefinition.
Facets for prices only work with Embedded Prices, there is currently no support for StandalonePrices.
FacetExpression
FacetResult
A PagedQueryResult contains a facets
object with all FacetResults.
A FacetResult can be accessed by its alias
if one was given in the FacetExpression or by its attributePath
otherwise.
Consider for example the following two facets:
variants.attributes.color:red as red-things
variants.attributes.size:"m"
Their FacetResults would be included in the PagedQueryResult like seen here:
{"offset": 0,"count": 0,"results": [],"facets": {"red-things": {"type": "filter","count": 0},"variants.attributes.size": {"type": "filter","count": 0}}}
TermFacet
TermFacetExpression
To retrieve facet counts for all occurring values of a ProductVariant field the following notations can be applied:
categories.id
Counts the ProductVariants of all categories. Other built-in fields can be requested analogously.reviewRatingStatistics.averageRating
orreviewRatingStatistics.highestRating
orreviewRatingStatistics.lowestRating
Counts the ProductVariants for all occurringaverageRating
(or highestRating or lowestRating).reviewRatingStatistics.count
Counts the ProductVariants for all occurring review ratings count.variants.availability.availableQuantity
Counts the ProductVariants for all occurringavailableQuantity
.variants.availability.channels.<channel-id>.availableQuantity
Counts the ProductVariants for all occurringavailableQuantity
for the supply channel with ID<channel-id>
.variants.attributes.{name}
Counts the ProductVariants for all occurring values of custom simple value attributes such astext
,date
,time
,datetime
,boolean
andnumber
.variants.attributes.{name}.{lang}
Counts the ProductVariants for all occurring values of customltext
attributes in the given language.variants.attributes.{name}.key
Counts the ProductVariants for all occurringenum
orlenum
custom attribute keys.variants.attributes.{name}.label
Counts the ProductVariants for all occurringenum
custom attribute labels.variants.attributes.{name}.label.{lang}
Counts the ProductVariants for all occurringlenum
custom attribute labels in the given language.variants.attributes.{name}.centAmount
Counts the ProductVariants for all occurring values of a custommoney
attribute.variants.attributes.{name}.currencyCode
Counts the ProductVariants for all occurring currency codes of a custommoney
attribute.
TermFacetResult
The term type facets provide the counts for each of the different values the query parameter happens to have. This is useful for, for example, obtaining all possible values of a product attribute to provide filters for those values on the frontend.
type
-terms
dataType
- one oftext
,date
,time
,datetime
,boolean
ornumber
missing
- number of variants that have no value for the specified TermFacetExpressiontotal
- the total number of terms matching the TermFacetExpression.
The number represents an amount of products in case the term facet expression refers to product fields likecategories.id
andreviewRatingStatistics.count
. In case the expression is defined for fields specific to product variants, for example,variants.attributes.{name}
, the count represents the number of variants matching the expression.other
- the amount of terms that are not represented in this object (for example the amount of terms going beyond the limit of 200)terms
- Array of FacetTerm
FacetTerm
term
- one of the values for the field specified in TermFacetExpression for which at least one ProductVariant could be foundcount
- amount of ProductVariants for which theterm
appliesproductCount
- amount of Products for which theterm
applies. Only available ifcounting products
is enabled.
Note: FacetTerms in TermFacetResults are returned in descending order of their count
by default.
If the TermFacetExpression specifies to count Products via the counting products
extention then FacetTerms are instead returned in descending order of their productCount
.
RangeFacet
RangeFacetExpression
To aggregate facet counts across ranges of values, the range
qualifier can be applied analogous to the filter parameters. The :range
notation is applicable to the date
, time
, datetime
, number
and money
type fields. It is also applicable to a set
of these types, in this case if one matching element is contained in the set
, all elements will be used in the aggregation.
Examples:
variants.price.centAmount:range ({from} to {to}), ({from} to {to}), ...
Counts the ProductVariants which Embedded Price falls in one of the specified ranges, lower and upper bound included.variants.price.centAmount:range (* to 50), (50 to 100), (100 to *)
Counts the ProductVariants which Embedded Price is below 50, between 50 and 100, and above 100.variants.scopedPrice.currentValue.centAmount:range (* to 1000), (1000 to 2000), (2000 to 3000)
Counts the ProductVariants whichcurrentValue
of the ScopedPrice is below 1000, between 1000 and 2000, and between 2000 and 3000 cents.variants.attributes.{name}:range ({from} to {to}), ({from} to {to}), ...
Counts the ProductVariants whose values of the custom attribute fall in one of the specified ranges, lower and upper bound included.
RangeFacetResult
The range facet type counts the ProductVariants for which the query value is a range specified in the RangeFacetExpression. RangeFacets are typically used to determine the minimum and maximum value, for example from a Product's Embedded Prices, to filter products by price with a range slider.
type
-range
ranges
- array of Range
Range
Range facets provide statistical data over values for date
, time
, datetime
, number
and money
type fields in a RangeFacetResult.
from
- Number - The range's lower endpoint in number format, 0 represents -∞.fromStr
- String - The range's lower endpoint in string format, empty string represents -∞.to
- Number - The range's upper endpoint in number format, 0 represents +∞.toStr
- String - The range's upper endpoint in string format, empty string represents +∞.count
- Number - Amount of ProductVariants for which the values in a field fall into the specified range.productCount
- Number - Amount of Products for which the values in a field fall into the specified range. Only available ifcounting products
is enabled.total
- Number - Sum of all values contained in the range.min
- Number - Minimum value among all values contained within the range.max
- Number - Maximum value among all values contained within the range.mean
- Number - Arithmetic mean of the values contained within the range.
FilteredFacet
FilteredFacetExpression
To get facet counts just for a specific field value, the requested value can be appended after a colon. This notation can be applied to any kind of field analogous to the filter parameters.
Examples:
categories.id:"{id}"
Counts the ProductVariants in the specified category.categories.id: subtree("{id}")
Counts the ProductVariants in the subtree of the specified category.categories.id: subtree("{id1}"), subtree("{id2}")
Counts the ProductVariants for each of the given subtrees.
Unlike filters, facets usingsubtree
can not be mixed with regular value facets, socategories.id: subtree("{id}"), "{id2}"
will ignore {id2}.categories.id: subtree("*")
The asterisk parameter is equivalent to counting the ProductVariants that have a category assigned.variants.price.centAmount:{amount}
Counts the ProductVariants having the specified Embedded Price.variants.attributes.{name}:{value}
Counts the ProductVariants with the custom attribute matching the specified value of a simple custom attribute. String values must be set in quotation marks. Add the respective postfixes for other attribute types analogous to when requesting facets for all values (see above).variants.attributes.{name}:{value},{value2}
Counts the ProductVariants with the custom attribute matching at least one of the values in the comma-separated list.variants.attributes.{myEnumName}.key:"{value}"
Counts the occurrences of a specific enum key.
FilteredFacetResult
This facet type provides counts for specific values of ProductVariant fields.
type
-filter
count
- number of ProductVariants matching the value specified in the FilteredFacetExpressionproductCount
- number of Products matching the value specified in the FilteredFacetExpression. Only available ifcounting products
is enabled.
FacetExpression Extensions
Alias
All facets can optionally be given an alias which will be used instead of the attribute path in the result. This makes it possible to calculate multiple facets on the same attribute in the same search request.
Examples:
variants.attributes.color.key:red as {alias}
Returns the facet with a sensible name (default would be just the attribute name)variants.attributes.brand:"Coca-Cola" as brand_coke
plusvariants.attributes.brand:"Pepsi" as brand_pepsi
Returns the facet counts for two specific values of the same attribute without causing a naming conflictvariants.price.centAmount:range(0 to 9999) as price_below_100
plusvariants.price.centAmount
Allows to show a marketing hint about many products cheaper than 100 on a page that also shows the normal price filter.
Counting Products
All facets can optionally count Products additionally to ProductVariants.
Appending counting products
to a FacetExpression enables the counting of Products.
The FacetResult will then contain an additional field productCount
that shows the number of Products.
Examples:
variants.attributes.color.key counting products
Returns a FacetResult containing for each FacetTerm (in this case for each color)- the number of ProductVariants with that color
- the number of Products that have at least one ProductVariant with that color.
variants.price.centAmount:range (0 to 10000) counting products
Returns a FacetResult containing for each Range- the number of ProductVariants that have an Embedded Price in that Range
- the number of Products that have at least one ProductVariant with an Embedded Price in that Range.
variants.attributes.color.key:red counting products
Returns a FacetResult counting- the number of ProductVariants that are red
- the number of Products that have at least one red ProductVariant.
categories.id:"{id}" counting products
Returns a facet result containing- the number of Products in the specified category
- the sum of all ProductVariants of these Products.
Sorting
By default, search results are sorted descending by their relevancy with respect to the provided text
(that is their "score").
An alternative sorting can be specified via the sort
query parameter which has the structure {field} {direction}
.
Compound sorting (also known as multi-sort) is applied when specifying multiple sort query parameters ordered by priority in which each parameter has its own sorting direction.
Direction can be asc
(ascending) or desc
(descending).
If the sort
parameters do not sufficiently define an ordering, the position of some or all products can be nondeterministic, that is not predictable and not repeatable across API requests.
Common cases include:
- When neither a
text
nor asort
parameter is given, the complete order is nondeterministic. - When full text is provided, but no
sort
parameter is given, the results are returned in descending order of relevance. - When products have no value set on the fields that are the sort criteria, the position is nondeterministic among those with no value set.
- When products have identical values on the fields that are the sort criteria, the position among each group with identical values is nondeterministic.
To achieve deterministic order, always have a sort
parameter at the end of the list of sort
parameters that sorts by a field or attribute that has distinct values across all products, for example createdAt
or a custom attribute specific for this purpose.
The following are valid standard fields to sort by:
name.{language}
Sorts the products by name. Field must include the language in form of an IETF language tag.categoryOrderHints.{category ID}
Combined with a filter by category, sorts the products by the category order hintcreatedAt
Sorts the products by creation date.lastModifiedAt
Sorts the products by modification date.id
Sorts the products by ID.score
Explicitly sorts the products by search relevance score.
Example for ascending sort
parameter: name.de asc
Sorting by score
may be combined with other sorting criteria. For example, sorting by score
and then by id
will ensure
consistent products order across several search requests for products that have the same relevance score.
Sorting by Price
To sort products by price:
price
Sorts the products by their Embedded Price.
Since prices can vary across variants of a single product, the following behavior applies: When the sort direction is descending, the highest Embedded Price of a product is used for sorting. When the sort direction is ascending, the lowest Embedded Price is used.
Currently only the centAmount
of the first Embedded Price from the prices of every ProductVariant is used for sorting. If you have more than one Embedded Price defined per Product Variant, consider sorting by Scoped Price instead.
Sorting by price only works with Embedded Prices, there is currently no support for StandalonePrices.
Sorting by Scoped Price
To be able to sort products by their variant's scopedPrice
you must use Scoped Price Search.
variants.scopedPrice.value
Sorts the products by their ScopedPricevalue
.variants.scopedPrice.currentValue
Sorts the products by their ScopedPricecurrentValue
.
Sorting by value
or currentValue
might return an unexpected result if you don't specify one of their subfields. For example, to sort by the numerical value of the Price, you must specify the .centAmount
subfield as follows: variants.scopedPrice.currentValue.centAmount
.
Since prices can vary across variants of a single product, the following behavior applies: When the sort direction is descending, the highest Embedded Price of a product is used for sorting. When the sort direction is ascending, the lowest Embedded Price is used.
This feature compares only Embedded Prices matching exactly the Price Selection Parameters given with the Scoped Price Search request and is therefore the safer option when there is more than one Price on a Product Variant compared to sorting by Price.
Sorting by price only works with Embedded Prices, there is currently no support for StandalonePrices.
Sorting by Reviews
To sort products by reviews:
reviewRatingStatistics.averageRating
Sorts the products by the average review rating.reviewRatingStatistics.highestRating
Sorts the products by the highest review rating.reviewRatingStatistics.lowestRating
Sorts the products by the lowest review rating.reviewRatingStatistics.count
Sorts the products by the number of reviews ratings.
Sorting by values found on ProductVariants
If products have several ProductVariants each variant can have a different value on the sorted attribute.
For those products it needs to be specified whether the minimum or the maximum value across the variants is used to compare this product with other products.
By default, the minimum value is used when sorting in ascending order (asc.min
) and the maximum value is used when sorting in descending order (desc.max
).
If a different sorting behavior is desired the parameters can be set to asc.max
or desc.min
respectively.
The field names to sort products by values found on ProductVariants start with variants.
.
Sorting by SKU
To sort by SKU:
variants.sku
Sort the products alphabetically by SKU
Sorting by Availability
To sort products by availability:
variants.availability.restockableInDays
Sort the products by number of days it takes to restock it (with no supply channel)variants.availability.channels.<channel-id>.restockableInDays
Sort the products by number of days it takes to restock it for a specific supply channelvariants.availability.availableQuantity
Sort the products by available quantity (with no supply channel)variants.availability.channels.<channel-id>.availableQuantity
Sort the products by available quantity for a specific supply channel
Example sort
parameter for availableQuantity
:
variants.availability.availableQuantity desc.min
Sorting by Attributes
In addition to the sorting by the standard fields listed above, products can also be sorted by their specific custom attributes. Please note that the search endpoint only supports those custom attributes that have been declared as searchable in the ProductType.
To sort by a custom attribute value, the custom attribute must have the isSearchable
field set to true
in its AttributeDefinition.
The following are valid attribute fields to sort by:
variants.attributes.{name}
Sort the products by simple value attributes such astext
,date
,time
,datetime
,boolean
andnumber
.variants.attributes.{name}.{lang}
Sort the products byltext
attribute in a specific language.variants.attributes.{name}.key
Sort the products byenum
orlenum
attribute key.variants.attributes.{name}.label
Sort the products byenum
attribute label.variants.attributes.{name}.label.{lang}
Sort the products bylenum
attribute label in a specific language.variants.attributes.{name}.centAmount
Sort the products bymoney
attribute amount.variants.attributes.{name}.currencyCode
Sort the products bymoney
attribute currency.
Example sort
parameter for lenum
attribute color:
variants.attributes.color.label.en asc.max