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.

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:

{
"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.

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 to false)
    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 if fuzzy is enabled. This value can not be higher than the default one based on the length of the searched text.

  • filter - Filter - Optional

  • filter.query - Filter - Optional

  • filter.facets - Filter - Optional

  • facet - Facets - Optional

  • sort - Sort - Optional

  • limit - Number - Optional

  • offset - Number - Optional

  • staged - Boolean - Optional (defaults to false)
    Whether to search in the current or staged projections.
    When using the OAuth 2.0 scope view_published_products, it is not permitted to use staged = true.

  • markMatchingVariants - Boolean - Optional (defaults to false)
    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 the priceCurrency parameter.

  • priceCustomerGroup - UUID - Optional
    Enables price selection and Scoped Price Search. Can only be used in conjunction with the priceCurrency parameter.

  • priceChannel - UUID - Optional
    Enables price selection and Scoped Price Search. Can only be used in conjunction with the priceCurrency 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 in application/x-www-form-urlencoded.

Example GET request

GET /{projectKey}/product-projections/search?staged=true&limit=10&text.en="simpsons"

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:

If no sort parameter is given, the results are sorted by the relevance of the product to the search text passed.

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 over filter.
  • 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 a filter parameter. This behavior in combination with the filter 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 or reviewRatingStatistics.highestRating or reviewRatingStatistics.lowestRating
    Counts the ProductVariants for all occurring averageRating (or highestRating or lowestRating).
  • reviewRatingStatistics.count
    Counts the ProductVariants for all occurring review ratings count.
  • variants.availability.availableQuantity
    Counts the ProductVariants for all occurring availableQuantity.
  • variants.availability.channels.<channel-id>.availableQuantity
    Counts the ProductVariants for all occurring availableQuantity for the supply channel with ID <channel-id>.
  • variants.attributes.{name}
    Counts the ProductVariants for all occurring values of custom simple value attributes such as text, date, time, datetime, boolean and number.
  • variants.attributes.{name}.{lang}
    Counts the ProductVariants for all occurring values of custom ltext attributes in the given language.
  • variants.attributes.{name}.key
    Counts the ProductVariants for all occurring enum or lenum custom attribute keys.
  • variants.attributes.{name}.label
    Counts the ProductVariants for all occurring enum custom attribute labels.
  • variants.attributes.{name}.label.{lang}
    Counts the ProductVariants for all occurring lenum custom attribute labels in the given language.
  • variants.attributes.{name}.centAmount
    Counts the ProductVariants for all occurring values of a custom money attribute.
  • variants.attributes.{name}.currencyCode
    Counts the ProductVariants for all occurring currency codes of a custom money 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 of text, date, time, datetime, boolean or number
  • missing - number of variants that have no value for the specified TermFacetExpression
  • total - 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 like categories.id and reviewRatingStatistics.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

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 which currentValue 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 if counting 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 using subtree can not be mixed with regular value facets, so categories.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.

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 plus variants.attributes.brand:"Pepsi" as brand_pepsi
    Returns the facet counts for two specific values of the same attribute without causing a naming conflict
  • variants.price.centAmount:range(0 to 9999) as price_below_100 plus variants.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:

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 a sort 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 hint
  • createdAt
    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:

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 ScopedPrice value.
  • variants.scopedPrice.currentValue
    Sorts the products by their ScopedPrice currentValue.

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 channel
  • variants.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 as text, date, time, datetime, boolean and number.
  • variants.attributes.{name}.{lang}
    Sort the products by ltextattribute in a specific language.
  • variants.attributes.{name}.key
    Sort the products by enum or lenum attribute key.
  • variants.attributes.{name}.label
    Sort the products by enum attribute label.
  • variants.attributes.{name}.label.{lang}
    Sort the products by lenum attribute label in a specific language.
  • variants.attributes.{name}.centAmount
    Sort the products by money attribute amount.
  • variants.attributes.{name}.currencyCode
    Sort the products by money attribute currency.

Example sort parameter for lenum attribute color:
variants.attributes.color.label.en asc.max