Product Projection Search

Product projections can be retrieved using full-text search, filtering and faceting functionality.

Search ProductProjections

This endpoint provides high performance search queries over ProductProjections.
The query result contains the ProductProjections for which at least one ProductVariant matches the search query. This means that variants can be included in the result also for which the search query does not match.

Endpoint: /{projectKey}/product-projections/search
Method: GET or POST
OAuth2 Scopes: view_products:{projectKey}
Response Representation: PagedQueryResult with the results array of ProductProjection

Mark matching variants:

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.

Parameters:

  • text.{language} - String - Optional
    The text to analyze and search for, e.g. 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, i.e. the full-text search is only performed in the localized product content of the specified language.
  • 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)
    Provide explicitly the fuzzy level desired if fuzzy is enabled. This value can not be higher than the one chosen by the platform by default.
  • 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.
  • 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.
  • 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 the priceCurrency parameter.
  • priceCustomerGroup - UUID - Optional
    Enables price selection. Can only be used in conjunction with the priceCurrency parameter.
  • priceChannel - UUID - Optional
    Enables price selection. Can only be used in conjunction with the priceCurrency parameter.

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 in  application/x-www-form-urlencoded.

Example GET request

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

The text.{language} query parameter performs the full-text search on the ProductProjections.

The text search includes the name, description, slug, sku and searchKeywords fields by default.
Custom attributes of the types text and ltext as well as the label of enum and lenum attributes are considered in the product search only after they have been defined as isSearchable in their AttributeDefinition.
On the localized fields ltext and lenum, the full text search will only consider the content in the language that was passed via the {language} part of the text parameter. If that language is not filled in the localized fields, nothing will be found.
The non-localized fields text and enum are always included, regardless of the language parameter.
The fields metaKeywords and metaTitle are currently not supported by the full-text search.

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

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 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

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

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 normally applied for carts and during search, scoped price filtering does not have any scope fallback behaviour and does not take the price validity date into consideration. This means that if a product variant, for instance, has 2 prices defined:

  1. country: US, value: 10 USD
  2. 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

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

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

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

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

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

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

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 on the key of the PlainEnumValue:

variants.attributes.{myEnumName}.key:"{value}"

In case of MoneyType attributes, the filter must be applied on 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 on 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.

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, e.g., 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, e.g., 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 (e.g. 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 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 e.g. 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 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 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 (i.e. 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, i.e. 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 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, e.g. 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 the centAmount 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 hint
  • createdAt
    Sorts the products by creation date.
  • lastModifiedAt
    Sorts the products by modification date.
  • id
    Sorts the products by id.

Example for ascending sort parameter: name.de asc

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

Besides sorting by the standard fields listed before, 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 make a custom attribute searchable the isSearchable flag must be set to true in the 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

Reference Expansion

Product projection search supports reference expansion. At the moment only references to the following resources can be expanded: