Skip to main content

Variations data in results

When returning search results each item with variations can include all data about its variations. This data may be necessary to display swatches that relate to different variations next to each product. But not all the attributes are required for such swatches. It can be only an image URL for each variation that's visually different (e.g. has a different color). With all not needed data, the response can be unnecessarily bloated and cause slowdowns, especially if number of variations is big. Finally, the default format of variations simply can be inconvenient to use client-side.

Example variations

Let's take a look at example variations returned in default format:

{
"response": {
"result_sources": {...},
"facets": [...],
"groups": [...],
"results": [
{
"matched_terms": [
"short"
],
"data": {
"id": "123",
"sku": "1001:101",
"url": "https://example.com/best-shorts",
"image_url": "https://example.com/best-shorts/red.jpg",
"size": "S",
"color": "red",
"price": 10,
"variations": [
{
"data": {
"sku": "1001:101",
"image_url": "https://example.com/best-shorts/red_s.jpg",
"size": "S",
"color": "red",
"price": 10
},
"value": "Hot shorts",
},
{
"data": {
"sku": "1001:102",
"image_url": "https://example.com/best-shorts/red_m.jpg",
"size": "M",
"color": "red",
"price": 20
},
"value": "Hot shorts",
},
{
"data": {
"sku": "1001:110",
"image_url": "https://example.com/best-shorts/blue.jpg",
"size": "L",
"color": "blue",
"price": 30
},
"value": "Cool shorts",
}
]
}
}
]
}
}

To render a product swatch from the date above, one has to iterate over the variations array and get needed attributes, or build another data structure from it, but in any case throw away data that is not needed. Endpoints that are used to retrieve results (such as the search endpoint) provide an ability to request only necessary data and in a suitable format straightaway. For example, to get variations data in the following format:

{
"red": {
"sizes": ["S", "M"]
},
"blue": {
"sizes": ["L"]
}
}

one has to add the following JSON string under the variations_map query-string parameter when calling /search and expect variations data of the format also in variations_map field of each result.

{
"group_by": [
{
"name": "color",
"field": "data.color"
}
],
"values": {
"sizes": {
"aggregation": "all",
"field": "data.size"
}
},
"dtype": "object"
}

As you may notice, it's also possible to group variations and aggregate their fields. In particular, you can ask for min and max prices across all item variations or return only the first image URL instead of all variation pictures.

Syntax

The variations_map parameter value must be a valid JSON with the following schema:

{
"group_by": [
{"name": "<alias>", "field": "<field path>"},
...
],
"values": {
"<alias>": {
"aggregation": "first" | "min" | "max" | "all",
"field": "<field path>"
},
...
},
"dtype": "array" | "object"
}

where:

  • <alias> is any name you want to use to refer to a certain field in the response
  • <field path> is the location of the field that's being referenced. Nested fields can be referenced here, using . as a separator (e.g data.color)
  • group_by is the optional clause that specifies how variations should be grouped. Multiple values can be passed if you want the variations to be grouped by a combination of attributes. If omitted or empty array aggregation will happen on all variations, without any grouping.
  • values is the clause that specifies which fields you want to retrieve from each group and how to aggregate them.
    • each value in values contains:
      • field that should be aggregated
      • aggregation - the aggregation function. Current accepted values are min, max, first and all.
  • dtype defines the type of the variations_map that will be returned in the response. It can be either array or object

More examples

The following example using the variations above returns them in the form of a nested object, where the first-level key is a color, and the second-level key is a size. In addition, minimum and maximum prices are returned in separate fields, and images of all variations are collected into a single array image_urls, while the first element of that array is stored in main_image_url.

Mapping configuration

{
"group_by": [
{
"name": "color",
"field": "data.color"
},
{
"name": "size",
"field": "data.size"
}
],
"values": {
"min_price": {
"aggregation": "min",
"field": "data.price"
},
"max_price": {
"aggregation": "max",
"field": "data.price"
},
"main_image_url": {
"aggregation": "first",
"field": "data.image_url"
},
"image_urls": {
"aggregation": "all",
"field": "data.image_url"
}
},
"dtype": "object"
}

^ That is to say: group all variations by color and then by size & for each group of variations with the same color and size return the first image_url, min and max prices, and also collect urls of all images into image_urls.

Result

{
"red": {
"S": {
"min_price": 10,
"max_price": 20,
"main_image_url": "https://example.com/best-shorts/red_s.jpg",
"image_urls": [
"https://example.com/best-shorts/red_s.jpg",
"https://example.com/best-shorts/red_m.jpg"
]
},
"M": {
"min_price": 10,
"max_price": 20,
"main_image_url": "https://example.com/best-shorts/red_s.jpg",
"image_urls": [
"https://example.com/best-shorts/red_s.jpg",
"https://example.com/best-shorts/red_m.jpg"
]
}
},
"blue": {
"L": {
"min_price": 30,
"max_price": 30,
"main_image_url": "https://example.com/best-shorts/blue.jpg",
"image_urls": ["https://example.com/best-shorts/blue.jpg"]
}
}
}

If you change dtype to array the result will be the following. Note that the grouping attributes color and size are included automatically, without specifying them in values.

[
{
"color": "red",
"size": "S",
"min_price": 10,
"max_price": 20,
"main_image_url": "https://example.com/best-shorts/red_s.jpg",
"image_urls": [
"https://example.com/best-shorts/red_s.jpg",
"https://example.com/best-shorts/red_m.jpg"
]
},
{
"color": "red",
"size": "M",
"min_price": 10,
"max_price": 20,
"main_image_url": "https://example.com/best-shorts/red_s.jpg",
"image_urls": [
"https://example.com/best-shorts/red_s.jpg",
"https://example.com/best-shorts/red_m.jpg"
]
},
{
"color": "blue",
"size": "L",
"min_price": 30,
"max_price": 30,
"main_image_url": "https://example.com/best-shorts/blue.jpg",
"image_urls": ["https://example.com/best-shorts/blue.jpg"]
}
]

If you skip group_by and request something like:

{
"values": {
"min_price": {
"aggregation": "min",
"field": "data.price"
},
"max_price": {
"aggregation": "max",
"field": "data.price"
}
},
"dtype": "array"
}

result is just an array and aggregation happens across all, not grouped, variations: [10, 30]. Same logic is applied in case of "dtype": "object", the result is {"min_price": 100, "max_price": 120}.