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.
Please check these performance tips to optimize the usage of this endpoint for your project.
To be able to use the Product Projection Search endpoint, your product catalog needs to be indexed first.
To activate the indexing for your projects, please choose one of the following options:
- via API using the Change Product Search Indexing Enabled update action on the Project endpoint.
- via the Merchant Center by navigating to Settings > Projects Settings > Storefront search.
- via contacting Support on the Support Portal and provide the region, project key(s), and use case(s).
Search ProductProjections
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.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)
Provide explicitly the fuzzy level desired iffuzzy
is enabled. This value can not be higher than the one chosen by the platform by default.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.priceCountry
- String - Optional
A two-digit country code as per ISO 3166-1 alpha-2. Enables price selection. Can only be used in conjunction with thepriceCurrency
parameter.priceCustomerGroup
- UUID - Optional
Enables price selection. Can only be used in conjunction with thepriceCurrency
parameter.priceChannel
- UUID - Optional
Enables price selection. Can only be used in conjunction with thepriceCurrency
parameter.storeProjection
- String - Optional
Key of an existing Store.
If the Store defines some languages, distribution channels or supply channels, they are used to enable locale based projection, price based projection and inventory based projection respectively.localeProjection
- String - Optional
IETF language tag.
Enables locale based projection.
To set more than one locale, use this query parameter multiple times.
Note that currently the price selection parameters only influence the scoped price sorting, filtering, and faceting.
Use it with caution though since scoped price search will not follow price fallback rules. Just like with price selection,
scopedPrice, and scopePriceDiscounted
would be selected based on the currency, country, customer group and channel.
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 PlainEnumValue 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 by the platform 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
, otherwise the platform selects level 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
Keep only the products which 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 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 price set:
variants.prices:exists
Price filters can be applied in the filter
, filter.query
and filter.facets
scopes.
Please note, that only the first price would be used for filtering if a product variant has several prices. If you would like to use some other product variant price (selected based on the price scope) then you need to use scoped price filter described in the next section.
Filter by scoped price
Scoped price is a price of a product variant selected based on the price scope like currency, country, channel, etc. In contrast to price selection logic usually applied for carts and during search, scoped price filtering does not have any scope fallback behavior and does not take the price validity date into consideration. This means that if a product variant, for instance, has 2 prices defined:
- country:
US
, value:10 USD
- country:
US
, customerGroup:B2B
, value:8 USD
And following price selector is used for filtering:
- country:
US
, customerGroup:B2C
Then no product will be returned: price will not be found and filtered because normal price fallback logic does not apply for scoped prices.
Price selector is used to specify which price should be filtered, faceted, and sorted. If price selector is not provided and scoped price filter is used in the search request, then search will yield no results.
Scoped price filters can be applied as filter
, filter.query
and filter.facets
parameters.
Filter by scopedPrice value
Filters, sorts, and facets products by the original product variant 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 price value or a discount price 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 a discount price 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 price.
Filter by SKU
Keep only the product which matches 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 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 product 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 EnumType, the filter must be applied to the key
of the PlainEnumValue:
variants.attributes.{myEnumName}.key:"{value}"
In case of MoneyType 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 ReferenceType 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 SetType 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.
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 whose 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 whose price is below 50, between 50 and 100, and above 100.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 product 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 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.attributes.price.centAmount:range (0 to 10000) counting products
Returns a FacetResult containing for each Range- the number of ProductVariants that have a price in that Range
- the number of Products that have at least one ProductVariant with a 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 multisort) 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 vales 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.price
Sorts the products by price. Since prices can vary across variants of a single product, the following behavior applies: When the sort direction is descending, the highest price of a product is used for sorting. When the sort direction is ascending, the lowest price is used. Currently only thecentAmount
of the first price from the prices of every ProductVariant is used for sorting.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 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
Reference Expansion
Product projection search supports reference expansion. At the moment only references to the following resources can be expanded: