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.gdata.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 aggregatedaggregation
- the aggregation function. Current accepted values aremin
,max
,first
andall
.
- each value in values contains:
dtype
defines the type of thevariations_map
that will be returned in the response. It can be eitherarray
orobject
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}
.