Facets Guide
editFacets Guide
editFacets are all about enriching your search query responses.
A facet is a tool that your users can use to further tune search results to their liking.
It will generate a count
for a value
or range
based on a field within a schema.
We can see facets in action within a hosted Search UI displaying the National Parks demo: https://parks.swiftype.info/.
Facets - A visual example of facets from the eyes of the Search UI.
Facets are contained on the left side, next to the results.
The example link is faceting on two different fields: world_heritage_site
and states
.
A query like "old growth" will return many different parks. Someone browsing for parks will want to dig deeper into the result set.
A facet is added to a field to provide a count of results that share values within that field. This makes much more sense visually...
Facets - Facets, up close and personalized.
Parks with "states": ['California']
, "states": ['Colorado']
, "states": ['Nevada']
, and so on, are counted together as a facet. A user can now click into the facet, returning only results that contain that value: California, Colorado, Nevada, or otherwise.
Facets - The "old growth" query with California as a facet.
Once within one facet, the other faceted fields are still available to us.
There are two "old growth" parks in California: one is a world heritage site and one is not.
Each time we click into a facet, the result set is refined until we reach the right result.
But what do these queries look like in the eyes of the code?
curl -X GET '<ENTERPRISE_SEARCH_BASE_URL>/api/as/v1/engines/national-parks-demo/search' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer search-soaewu2ye6uc45dr8mcd54v8' \ -d '{ "query": "old growth", "facets": { "states": [ { "type": "value" } ], "world_heritage_site": [ { "type": "value" } ] } }'
It is a query to the /search
endpoint with two Value Facets, which are only available within text fields.
There are three other types of field: number, date, and geolocation. What if we want to facet on those fields?
We would apply a Range Facet.
You can imagine how that might work...
If you want to find products within a certain price range, restaurants at a certain distance, or concerts on a particular date, you would apply a Range Facet.
Staying on the trail of our National Park demo, how would we sort parks by their level of busy-ness?
curl -X GET '<ENTERPRISE_SEARCH_BASE_URL>/api/as/v1/engines/national-parks-demo/search' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer search-soaewu2ye6uc45dr8mcd54v8' \ -d '{ "query": "old growth", "facets": { "visitors": [ { "type": "range", "ranges": [ { "from": 1, "to": 150000, "name": "Not busy" }, { "from": 150000, "to": 500000, "name": "Somewhat busy" }, { "from": 500000, "name": "Very busy"} ] } ] } }'
We would facet on the visitors
field, which is of type number.
We create three "buckets", each with a name indicating how busy the park is over the course of a year.
The resulting count for the "old growth" query would then look like this:
{ "meta": { ## Truncated!! }, "request_id": "e3e8f493cb7f8577001910ca77c3fd24" }, "results": [ ## Truncated! ], "facets": { "visitors": [ { "type": "range", "data": [ { "to": 150000, "from": 1, "name": "Not busy", "count": 2 }, { "to": 500000, "from": 150000, "name": "Somewhat busy", "count": 2 }, { "from": 500000, "name": "Very busy", "count": 6 } ] } ] } }
That looks good. But we know that facets can be combined.
A person looking for "old growth" parks wants to find the one that is the least busy, and that is the closest to where they live.
If the schema has a field of type geolocation, they can apply another Range Facet to extend the query, like so:
curl -X GET '<ENTERPRISE_SEARCH_BASE_URL>/api/as/v1/engines/national-parks-demo/search' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer search-soaewu2ye6uc45dr8mcd54v8' \ -d '{ "query": "old growth", "facets": { "visitors": [ { "type": "range", "ranges": [ { "from": 1, "to": 150000, "name": "Not busy" }, { "from": 150000, "to": 500000, "name": "Somewhat busy" }, { "from": 500000, "name": "Very busy"} ] } ], "location": [ { "type": "range", "center": "37.386483, -122.083842", "unit": "m", "ranges": [ { "from": 0, "to": 100000, "name": "Close" }, { "from": 100000, "to": 300000, "name": "A weekend trip" }, { "from": 300000, "name": "Far from home" } ] } ] } }'
We provided the coordinates of the Elastic office in Mountain View, California as our center and distance in meters.
As expected, the full result set for the "old growth" queries appear, and so do the counts:
"facets": { "location": [ { "type": "range", "data": [ { "to": 100000, "from": 0, "name": "Close", "count": 0 }, { "to": 300000, "from": 100000, "name": "A weekend trip", "count": 1 }, { "from": 300000, "name": "Far from home", "count": 9 } ] } ], "visitors": [ { "type": "range", "data": [ { "to": 150000, "from": 1, "name": "Not busy", "count": 2 }, { "to": 500000, "from": 150000, "name": "Somewhat busy", "count": 2 }, { "from": 500000, "name": "Very busy", "count": 6 } ] } ] }
In a few clicks within the search experience, a person can query for old growth parks and find the nearest, least busy park.
For a full list of potential facets, check out the Facets API Reference.
What’s Next?
editYou are well on your way to getting a handle on search and its many... facets. Poor puns aside, there are many other features that can help you get the most out of App Search. You might want to learn how to gain insights into user search data. For that, Analytics and Clickthrough will serve you well. If you are looking to get into result tuning, consider Curations.