Hierarchical Facets Guide
App Search supports facets.
By combining them with filters, you can build hierarchical facets.
Consider how facets work in the National Parks demo: https://parks.swiftype.info.
A typical list of facets has one dimension.
If we query the above demo site for "parks", we see our two facets:
States
World Heritage Site
With hierarchical facets, facet counts - and results - get more granular as they are selected:
States
World Heritage Site
A prototypical example is an ecommerce store:
Shirts
T-shirts
Sweatshirts
Hoodies
Collared Shirts
Polo shirts
Dress shirts
Footwear
Sandals
Sneakers
Accessories
Scarves
Belts
Continuing with parks, we will demonstrate how to write hierarchical facet queries.
In motion, here is how they work:
After searching for "parks", the state
facet appears...
California (8)
Alaska (5)
...
We click into one, and then the "second dimension", the child facet, appears:
California (8)
World Heritage Site (6)
Regular Site (2)
Alaska (5)
Our results also reflect what we have clicked.
We only see parks from "California".
Now we choose whether or not we want to visit a World Heritage Site.
We make our choice, and then...
California (8)
World Heritage Site (6)
Open (4)
Closed (2)
Alaska (5)
The results show only "California" parks that are "World Heritage Sites".
And the second child - "third dimension" - appears: open or closed?
And we can go on, and on!
We create fields, and then apply facets and filters to implement this.
We would model our document fields like this:
{
// ... Truncated!
"description": "I am a park! You know, for nature.",
"dimension1": "California",
"dimension2": "World_Heritage_Site",
"dimension3": "Open"
}
The "why" will become apparent as we build the queries:
{
"query": "parks",
"facets": {
"dimension1": [
{
"type": "value"
}
]
}
}
For our first query, we request results, plus a facet count of the first dimension.
In this case, that dimension gives US state names, and so we return a count of states:
{
// ... Truncated!
"facets": {
"dimension1": [
{
"type": "value",
"data": [
{
"value": "California",
"count": 8
},
{
"value": "Alaska",
"count": 5
},
// .. Truncated!
]
}
]
}
}
Looks as we would except -- it is, after all, a typical facet query.
Now, when a user clicks a parent, a first dimension facet, we apply a facet and a filter.
Imagine that a user clicked on "California".
It would invoke this query:
{
"query": "parks",
"facets": {
"dimension2": [
{
"type": "value"
}
]
},
"filters": {
"dimension1": ["California"]
}
}
A filter is applied on dimension1
to match on "California".
And a facet count is requested for the child field, dimension2
.
That field - dimension2
- tells us whether or not the park is a World Heritage Site.
The narrowed results appear, as does the count we expect:
{
// ... Truncated!
"facets": {
"dimension2": [
{
"type": "value",
"data": [
{
"value": "World_Heritage_Site",
"count": 6
},
{
"value": "Regular_Site",
"count": 2
}
]
}
]
}
}
In our path, we are here, returning only one faceted dimension:
World Heritage Site (6)
Regular Site (2)
With the next decision, the user will click further down the hierarchy.
If they click "World Heritage Site", then the next query requires two parts:
Facet on
dimension3
: whether the park isOpen
orClosed
.Add filters for
dimension1
anddimension2
to narrow results.
{
"query": "parks",
"facets": {
"dimension3": [{ "type": "value"}]
},
"filters": {
"all": [
{"dimension1": ["California"]},
{"dimension2": ["World_Heritage_Site"]}
]
}
}
Again, we return narrowed results and the right facet count:
{
// ... Truncated!
"facets": {
"dimension3": [
{
"type": "value",
"data": [
{
"value": "Open",
"count": 4
},
{
"value": "Closed",
"count": 2
}
]
}
]
}
}
Great! But one thing to consider is that the example only returned the dimension3
count.
Our facets would look like this:
Open (4)
Closed (2)
If we want the facet menu to include the correct counts for all dimensions, like so:
California (8)
World Heritage Site (6)
Open (4)
Closed (2)
Alaska (5)
We would use multiple queries:
- Request
dimension1
facets. - Request
dimension2
facets, filter ondimension1
. - Request
dimension3
facets, filter ondimension1
anddimension2
.
That's the hierarchical facets pattern! You can get as deep as you'd like.
You should now be well equipped to start building.
Read more: Facets Guide | Facets API Reference
Stuck? Looking for help? Contact support or check out the App Search community forum!