ALL YOU EVER
wanted to know
about
filters
AND
facets
in SPHERE.IO
API endpoints
Products: by ID, query
-
Full product (both current and staged)
-
Request to MongoDB
Product-projections: by ID, query, search
-
Partial product (current or staged only)
-
Request to MongoDB (query) and ElasticSearch (search)
products by ID
GET /products/{id}
{
"id": "04b8c147-0065-4ed6-8d30-b145215d4dd6", "masterData": { "staged": { "masterVariant": { ... }, "variants": [ ... ], }, "current": { "masterVariant": { ... }, "variants": [ ... ], }, "hasStagedChanges": false, }, }
products query
GET /products ? where={predicate}
& sort={criteria} & limit=20 & offset=0
{
"results": [
{
"id": "04b8c147-0065-4ed6-8d30-b145215d4dd6",
"masterData": {
"staged": {
"masterVariant": { ... },
},
"current": {
"masterVariant": { ... },
},
"hasStagedChanges": false,
},
}
],
"total": 100, "count": 20, "offset": 0
}
product-projections by ID
GET /product-projections/{id} ? staged=false
{
"id": "04b8c147-0065-4ed6-8d30-b145215d4dd6",
"masterVariant": { ... },
"hasStagedChanges": false,
}
product-projections query
GET /product-projections ? staged=false
& where={predicate} & sort={criteria}
& limit=20 & offset=0
{
"results": [
{
"id": "04b8c147-0065-4ed6-8d30-b145215d4dd6",
"masterVariant": { ... },
"hasStagedChanges": false,
}
],
"total": 100, "count": 20, "offset": 0
}
product-projections search
GET /product-projections/search ? lang=en & staged=false & text={search} &
facet={expression} & filter={expression} &
filter.query={expression} & filter.facets={expression}
& sort={criteria} & limit=20 & offset=0
{
"facets": { ... },
"results": [
{
"id": "04b8c147-0065-4ed6-8d30-b145215d4dd6",
"masterVariant": { ... },
"hasStagedChanges": false,
}
],
"total": 100, "count": 20, "offset": 0
}
search query parameters
search query parameters
search query parameters
search query parameters
search query parameters
search expressions
On product attributes:
-
category categories.id
-
price variants.price.centAmount
-
custom attribute variants.attributes.{name}
-
custom enum attribute variants.attributes.{name}.key
With expression types:
-
terms {x}, {y}, {z}
-
ranges {from} to {to}
term facets
GET /product-projections/search ? lang=de
& facet=variants.attributes.color.key
{
"facets": {
"variants.attributes.color.key": {
"terms": [
{ "count": 7, "term": "red" },
{ "count": 2, "term": "blue" }
],
"total": 9, // variants matching some returned term
"missing": 3, // variants with no matching term (no value)
"other": 0, // variants excluded from total (limit 50)
"type": "terms"
}
}
}
range facets
GET /product-projections/search ? lang=de
& facet=variants.price.centAmount: range (0 to *)
{
"facets": {
"variants.price.centAmount": {
"ranges": [
{
"mean": 16758.941464116207,
"max": 590000, "min": 50,
"from": 0, "fromStr": "0",
"to": 0, "toStr": "",
"count": 4165, "totalCount": 6953,
"total": 116524920,
}
],
"type": "range"
}
}
}
facet alias
GET /product-projections/search ? lang=de
& facet=variants.attributes.color.key as myFacet
{
"facets": {
"myFacet": {
"terms": [
{ "count": 7, "term": "red" },
{ "count": 2, "term": "blue" }
],
"total": 7, // variants matching some returned term
"missing": 3, // variants with no matching term (no value)
"other": 0, // variants excluded from total (limit 50)
"type": "terms"
}
}
}
facet alias: what to expect
facet alias: filtering alias
GET /product-projections/search ? lang=de
& facet=variants.attributes.color.key as myFacet
& filter.facets=myFacet: "red"
{
"facets": {
"myFacet": {
"terms": [],
"total": 0, // variants matching some returned term
"missing": 0, // variants with no matching term (no value)
"other": 0, // variants excluded from total (limit 50)
"type": "terms"
}
}
}
facet alias: filtering facet
GET /product-projections/search ? lang=de
& facet=variants.attributes.color.key as myFacet
& filter.facets= variants.attributes.color.key : "red"
{
"facets": {
"myFacet": {
"terms": [
{ "count": 7, "term": "red" },
{ "count": 2, "term": "blue" }
],
"total": 9, // variants matching some returned term
"missing": 3, // variants with no matching term (no value)
"other": 0, // variants excluded from total (limit 50)
"type": "terms"
}
}
}
SDK filter & facet expressions
SearchRequest<Product> searchRequest = sphere.products
.filter(List<FilterExpression>)
.facet(List<FacetExpression>);
SDK filters & facets
Conclusions
- The search API is the most important component
of SPHERE after the shopping cart logic.
- When a developer is not able to do a small thing with the search API, there is no painless alternative.
- Alternatives mean repeating pagination logic in the frontend and simulate sorting and filtering: expensive calls and expensive logic.
of SPHERE after the shopping cart logic.
Conclusions
-
API documentation is confusing: own section, better structure, some diagrams, more examples will help.
-
SDK is very confusing: dozens of classes, some cases of bad naming, not intuitive relation with API.
- The search API is very powerful, yet altogether makes it very hard to use it with complex cases.
That's all folks!
FF old
By Laura Luiz
FF old
- 1,894